string字符串为什么是java string 引用类型型

中国领先的IT技术网站
51CTO旗下网站
理解C# String类型:特殊的引用类型
C# String类型是值类型还是引用类型?一句话总结就是,它是特殊的引用类型。本文对于这个概念进行了比较详细的解答。
作者:51CTO整理来源:CSDN论坛| 16:39
有关C# String类型究竟是值类型还是引用类型,在很多C#学习者中都或多或少造成过困惑。好比下面这个例子:class&Class1& &{& &&&&&static&void&StrChange(string&str)& &&&&&{& &&&&&&&str&=&"hellow";& &&&&&}& &&&&&&static&void&Main()& &&&&&{& &&&&&&&string&str&=&"123";&&&&&&&StrChange(str);&&&&&&&Console.WriteLine(str);&&&&&}& &}& &
输出的结果是 "123" 。
那么,string 到底是值类型还是引用类型?有人会说,如果是值类型,结果倒还说的过去.但是string 的定义不是应该是引用类型么?如果是引用类型的话.输出的结果难度不应该是: "hellow"么?
解答这个问题的关键在于,C# string类型是特殊的引用类型,它的实例是只读的。这个地方要搞清楚语法和实现的区别 。在C#的语法中,
◆static void StrChange(string str) 是值传递
◆static void StrChange(ref string str) 是引用传递
但在实现上,static void StrChange(string str) 这种值传递,在函数体内对str进行修改之前,与函数外部的变量指向同一块内存,是“引用”传递,但在函数体内对str修改后,就会触发对该str重新分配一块内存。
所以说,String 是引用类型,不过是不可变的。对字符串做一些操作(比如大小写的转换、+=), 实际上是重新创建了一个字符串。这也是为什么在做大量字符串拼接的时候要使用StringBuilder 而不用+=。
有关C# String类型做为引用类型的特别之处,可以参看下例的示例及注释:&&& private&void&button2_Click(object&sender,&EventArgs&e)& &&&&&&&{& &&&&&&&&&&&string&str="aaa";& &&&&&&&&&&&&string&str1&=&& &&&&&&&&&&&str&=&"bbb";&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&string&str2&=&& &&&&&&& &&&&&&&&&&& &&&&&&&&& &&&&&&&&&&&if&(object.ReferenceEquals(&str1,str2))& &&&&&&&&&&&{& &&&&&&&&&&&&&&&MessageBox.Show("yes");& &&&&&&&&&&&}& &&&&&&&&&&&else& &&&&&&&&&&&{& &&&&&&&&&&&&&&&MessageBox.Show("no");& &&&&&&&&&&&}& &&&&&&&} &
最后回到一开始的那段代码。如果想下面这样编写:class&Class1& &{& &&&&& &&&&&static&string&StrChange(string&str)& &&&&&{& &&&&&&&str&=&"hellow";& &&&&&&&&&return&& &&&&&}& &&&&&static&void&Main()& &&&&&{& &&&&&&&&&string&str&=&"123";&&&&&&&&&str=StrChange(str);&&&&&&&&&Console.WriteLine(str);&&&&&}& &&&&& &}&&
这样输出的便是hellow了。
【编辑推荐】
【责任编辑: TEL:(010)】
大家都在看猜你喜欢
头条热点头条头条头条
24H热文一周话题本月最赞
讲师:92572人学习过
讲师:172114人学习过
讲师:12216人学习过
精选博文论坛热帖下载排行
它从最简单的地方入手,不仅讲述了JavaScript的基础知识,还讲述了JavsScript如何操作CSS、DOM等Ajax基础技术。而关于跨浏览器兼容问题的解...
订阅51CTO邮刊在 SegmentFault,解决技术问题
每个月,我们帮助 1000 万的开发者解决各种各样的技术问题。并助力他们在技术能力、职业生涯、影响力上获得提升。
一线的工程师、著名开源项目的作者们,都在这里:
获取验证码
已有账号?
标签:至少1个,最多5个
区分基本类型和引用类型
基本类型值指的是简单的数据段,而引用类型值指那些可能由多个值构成的对象。基本类型包含Undefined、Null、Boolean、Number、String,这5种基本数据类型是按值访问的,因为可以操作保存在变量中的实际值。而在操作对象时,实际上是在操作对象的引用而不是实际的对象。为了方便操作基本类型值,ECMAScript 还提供了 3 个特殊的引用类型:Boolean、Number 和String,以便于使用对象方法操作基本类型值,引用类型与基本包装类型的主要区别就是对象的生存期,基本包装类型自动创建,并在代码执行后自动销毁实例。
基本类型 String类型
Sring类型用于表示由零个或多个16位Unicode字符组成的字符序列,即字符串。
字符串可以由单引号和双引号组成,两者没有区别
var firstName = 'Nicholas';
var lastName = "Zakas";
字符串的特点:
ECMAScript中的字符串是不可变的。字符串一旦创建,它们的值就无法改变。要改变某个变量保存的字符串,首先要销毁原来的字符串,然后在用一个包含新值的字符串来填充该变量。
转化为字符串:
把一个值转化为一个字符串有两种方式。第一种使用toString()方法,数值,布尔值,对象,和字符串值 。但是null和undefined值没有这个方法。
var age = 11;
age.toString();
var bool =
bool.toString();
//可以传递参数,代表输出数值的基数。
age.toString(2);//11
基本包装类型 String类型
String类型是字符串的对象包装,可以使用String构造函数来创建。
var stringObject = new String("hello world");
所有String对象的方法也可以在所有基本的字符串值中访问到,其中继承的value(),toLocaleString()和toString()方法,都返回对象所表示的基本字符值。
String类型的方法
(一)字符方法charAt()和charCodeAt(),都接收一个参数,基于0的字符位置。charAt()返回给定位置的字符,charCodeAt()返回字符编码。(二)字符串操作方法concat()方法,接收任意多个参数,返回一个新的字符串,不改变原字符串。可以使用+代替。
var str = "hello";
str.concat("world")//helloworld
//str仍为hello
还提供3个基于字符串创建新字符串的方法:slice(),substr(),substring()。都接收一个或两个参数。第一个参数指定子字符串的开始位置,而slice(),substring()第二个参数表示字符串到哪里结束,substr()第二个参数指定返回的个数。都不会修改原字符串。推荐使用slice()
var str = "hello world";
str.slice(3);
//"lo world"
str.substring(3);
//"lo world"
str.substr(3);
//"lo world"
str.slice(3,7);
str.substring(3,7); //"lo w"
str.substr(3,7);
//"lo worl"
(三)字符串位置方法indexOf()和lastindexOf(),两个方法都是从一个字符串中搜索给定的子字符串,然后返回字符串的位置。如果没有找到则返回-1。一个从头开始,另一个从尾开始。
(四)trim()方法这个方法会创建一个字符串的副本,删除前置和后缀的空格。不改变原字符。
var str = "
str.trim();//hello
还有非标准的trimLeft(),trimRight(),用于删除字符串开头或末尾的空格
(五)字符串的模式匹配方法1.search()查找字符串,接受一个参数为正则表达式或字符串,返回一个与之匹配的子串的起始位置。若未找到返回-1。例 :javaScript.search(/script/i);//返回4 search属性不支持全局属性检索,所以会忽略修饰符g2.replace():用以执行检索与替换操作,接受两个参数,第一个参数是正则或字符串,第二个参数是要进行替换的字符串或一个函数,不修改原字符串 。若第一个参数是字符串,replace()则会直接搜索这个字符串如果想要替换所有子字符串,唯一办法就是提供一个正则表达式。而且还要指定(g)标志。
var text = "cat, bat, sat";
var res = text.replace(/at/g,"ond")
res//"cond, bond, sond"
text//"cat, bat, sat"
3.match()接受唯一一个参数,就是正则表达式,返回一个由匹配结果组成的数组。例:“1 plus 2 equal 3”.match(/d+/g/);//返回["1","2","3"]如果没有设置修饰符,,就不会进行全局检索,也会返回一个数组,数组的第一个元素保存匹配的字符串,余下的元素保存正则表达式中用圆括号括起来的子表达式。例:解析一个url
var url = /(\w+):\/\/([\w.]+)\/(\S*)/;
var text = "Visit my blog at /-david";
result = text.match(url);
if(result != null){
var fullurl = result[0];//"/-david"
var protocol = result[1];//"http"
var host = result[2];//""
var path = result[3];//"-david"
4.split()用以将调用它的字符串拆分为子串组成的数组,使用分隔符是split()的参数,返回一个数组。参数为字符串
“123,456,789”.split(","); //返回["123,"456","789"];
参数为正则
3,4 ,5”.split(/\s*,\s*/)//返回["1","2","3","4","5"]
(六)localeCompare()方法如果字符串在字母表中排在参数前,返回一个负数。如果相等,则返回0;如果字符串在字母表中排在参数之后,返回一个正数。
(七)fromCharCode()方法接收一个或多个字符编码,返回一个字符串
String.fromCharCode(104,101,101,108,111)//"hello"
引用类型Array
和其他语言一样,javaScript中的数组是一个有序列表。但和其他语言不同的是,javaScript数组的每一项可以保存任何类型的数据。
有两种基本方式,第一种使用Array构造函数,用new创建数组数组(new可以省略)
var colors = new Array("red","blue","green");
第二种使用字面量创建
var colors = ["red","blue","green"];
javaScript为数组专门提供push()和pop()方法,以便实现类似栈的行为。push()可以接收任意数量的参数,把他们添加到数组末尾,返回修改后数组的长度。pop()方法从数组末尾移除一项,减少数组的length值,返回移除的项。
结合使用shift(),push(),可以像使用队列一样的数组。同时使用unshift()和pop()方法,可以从相反的方向来模拟队列。shift():从数组头部删除一个元素,返回被移除的元素。unshift():从数组头部添加一个元素,返回数组的长度。
重排序方法
数组中已经存在两个可以直接用来重排序的方法:reverse()和sort()。
valvalues=[1,2,3,4,5];
values.reverse();
alert(values);//5,4,3,2,1
sort()方法按升序排列数组项,sort()方法可以接收一个函数作为参数,修改排序。
function compare(a,b){
if(a & b){
return -1;
else if(a & b){
var values = [4,5,1,3,2];
values.sort(compare);
alert(values);//1,2,3,4,5
对于数值型可以直接写成
function compare(a,b){
return a-b;//降序
concat(),将接收到的参数添加到数组的末尾,返回一个新数组,不修改原数组。
var colors
= ["red","green","blue"];
var colors2 = colors.concat("yellow","red");
alert(colors);//red,green,blue
alert(colors2);//red,green,blue,yellow,red
slice():能够基于当前数组中的一个多项创建一个新数组。slice()方法可以接收一个或两个参数,即返回项的起始和结束位置。不会影响原始数组。splice()方法有很多种用法,始终都是返回一个数组。直接修改原数组
var colors = ["red","green"];
//删除:指定2个参数:删除第一项的位置,和删除的项数,返回删除的项
var colors4 = colors.splice(0,2);
//插入:提供三个参数,起始位置,0(要删除的项数),要插入的项,返回空数组
var colors5 = colors.splice(0,0,'1','2');
//替换:提供3个参数,起始位置,要替换的项数,要插入的项,返回替换的项
var colors6 = colors.splice(0,2,'red','green');
indexOf()和lastIndexOf().两个方法都接收两个参数要查找的项和(查找的起始位置)。在比较第一个参数中的每一项时,会使用全等操作符。
javaScript定义了5个迭代方法。每个方法都接收两个参数:要在每一项上运行的函数和(运行该函数对象的作用域——影响this的值)。传入这些方法的函数会接收三个参数。数组项的值,该项在数组中的位置,数组对象本身。都不会修改数组的值。every():对数组中的每一项运行给定函数,如果该函数每一项都返回true,则返回true。filter():对数组中的每一项运行给定函数,返回该函数返回true的项组成的数组。forEach():对数组中的每一项运行给定函数,没有返回值。map():对数组中的每一项运行给定函数,返回每次函数调用结构组成的数组。some():对数组中的每一项运行给定函数,如果该函数对任意一项返回true,则返回true
var number = [1,2,3,4,5,4,3,2,1];
var everyResult = number.every(function(item,index,array){
return (item&2);
alert(everyResult);//false
var someResult = number.some(function(item,index,array){
return (item&2);
alert(someResult);//true
var filterResult = number.filter(function(item,index,array){
return item&2;
alert(filterResult);//[3, 4, 5, 4, 3]
var mapReuslt = number.map(function(item,index,array){
return item*2;
alert(mapResult);//[2, 4, 6, 8, 10, 8, 6, 4, 2]
var num = [];
var forEachResult = number.forEach(function(item,index,array){
if(item!=0){
alert(num);//""
alert(forEachResult)//undefined
Reduce()和reduceRight(),这两个方法都会迭代数组的所有项,然后构建一个最终返回的值。reduce()方法从数组的第一项开始,逐个遍历到最后。reduceRight()则相反.都接收两个参数:一个在每一项上调用的函数和(作为缩小基础的初始值)。调用的函数接收4个参数:前一值,当前值,项的索引和项的数组。这个函数返回的任何值都会作为参数返回。
//执行求和操作
var arr = [1,2,3,4,5];
var sum = arr.reduce(function(prev,cur,index,array){
return prev +
0 收藏&&|&&0
你可能感兴趣的文章
1 收藏,1.9k
3 收藏,1.1k
8 收藏,4.9k
本作品采用 署名-非商业性使用-禁止演绎 4.0 国际许可协议 进行许可
分享到微博?
我要该,理由是:1被浏览241分享邀请回答for(auto& c : temp)
相当于是for(char& c : temp)
而for(auto c : temp)
相当于是for(char c : temp)
也就是说不加 & 的话 c = toupper(c) 修改的只是字符串中字符的拷贝而不是字符串本身,结果就是字符串保持原样不变。52 条评论分享收藏感谢收起细说引用类型string StringBuilder class的特点
string是引用类型,但它也有一些值类型的特征。
string传值还是传引用,C#的string声明是一个String类,当然是传引用。不过,之所以有这个疑惑,多数是因为这个情况:
string a = &aaa&;
string b =
b = &bbb&;
这时候输出结果,结果发现a的值还没有变,分析一下:
string a = &aaa&; // a--&new String(&aaa&)
string b = // b--&a, 传引用
b = &bbb&; // b--&new String(&bbb&), 传引用,b用new string指向了一个新的字符串,a并没有变。
StringBuilder 是引用类型,如果需要对字符串进行操作的,建议用StringBuilder 。例如你需要不断的接拼字符串。必须引用System.Text
String 对象是不可改变的。每次使用 System.String 类中的方法之一时,都要在内存中创建一个新的字符串对象,这就需要为该新对象分配新的空间。在需要对字符串执行重复修改的情况下,与创建新的 String 对象相关的开销可能会非常昂贵。如果要修改字符串而不创建新的对象,则可以使用 System.Text.StringBuilder 类。例如,当在一个循环中将许多字符串连接在一起时,使用 StringBuilder 类可以提升性能。
class引用为型,无论怎么传值,都是传送引用
下面看一个极简单的例子:
namespace&TCP
&&&&public&class&Program
&&&&&&&&static&void&Main(string[]&args)
&&&&&&&&&&&&string&code&=&&C#&;
&&&&&&&&&&&&User&user&=&new&User(&Li&,&<span style="color: #&);
&&&&&&&&&&&&StringBuilder&str&=&new&StringBuilder();&&&&&&&&&&&&
&&&&&&&&&&&&str.Append(&A&);&&&&&&&&&&&&
&&&&&&&&&&&&editUser(user,&str,code);
&&&&&&&&&&&&Console.WriteLine(code);
&&&&&&&&&&&&Console.WriteLine(str);
&&&&&&&&&&&&Console.WriteLine(user.name);
&&&&&&&&&&&&Console.WriteLine(user.age);
&&&&&&&&&&&&Console.ReadLine();
&&&&&&&&public&static&void&editUser(User&user,&StringBuilder&str,string&code)
&&&&&&&&&&&&code&=&&VB.NET&;
&&&&&&&&&&&&str&=&str.Remove(<span style="color: #,&<span style="color: #);
&&&&&&&&&&&&str.Append(&E&);
&&&&&&&&&&&&user.name&=&&LEE&;
&&&&&&&&&&&&user.age&=&&<span style="color: #&;
&&&&public&class&User
&&&&&&&&private&string&_
&&&&&&&&private&string&_
&&&&&&&&public&User(string&name,&string&age)

我要回帖

更多关于 c string 引用类型 的文章

 

随机推荐