{
public static void MySwap(string a, string b)
{
string c;
c=a;
a=b;
b=c;
}
public static void Main()
{
string a = "a";
string b = "b";
MySwap(a,b);
Console.WriteLine("a={0},b={1}",a,b);
RL();
}
}
String类型是一个引用类型,那么传递给MySwap的参数就是String类型的引用,而不是值。
那么MySwap执行完后,a,b的值应该交换呀,但是事实上并没有交换。(必须采用ref强制引用声明才能交换)。
为什么传递引用参数,参数在函数之外却并没有被修改,难道.NET对于参数都是默认统一为值传递???
19 个解决方案
#1
你可以去看我这篇文章:http://blog.csdn.net/tslkfyh/archive/2005/07/13/423889.aspx
字符串是常量,string是引用类型,关键是在MySwap编译器做了一些手脚,在调用前把a,b的MySwap的参数a,b,但在myswap内部又得新给a,b(不是Main中的a,b)重新分配了空间出来后,没引用指向它们,被送往垃圾回收,而Main中的a,b始终没变,也就是我文中所说的,一个是传指针,一个是传指针的指针
字符串是常量,string是引用类型,关键是在MySwap编译器做了一些手脚,在调用前把a,b的MySwap的参数a,b,但在myswap内部又得新给a,b(不是Main中的a,b)重新分配了空间出来后,没引用指向它们,被送往垃圾回收,而Main中的a,b始终没变,也就是我文中所说的,一个是传指针,一个是传指针的指针
#2
string是种很特殊的类型,内部机制确实是引用类型,但使用起来和值类型一样
一句两句说不清的,网上有很多这方面的贴子,自己搜下吧
一句两句说不清的,网上有很多这方面的贴子,自己搜下吧
#3
string 是引用类型,
但 string 对象保留在堆上,不是堆栈上,
所以,当把一个字符串变量赋给另一个字符串变量时,会得到对内存中同一个字符串的两个引用
但 string 对象保留在堆上,不是堆栈上,
所以,当把一个字符串变量赋给另一个字符串变量时,会得到对内存中同一个字符串的两个引用
#4
string是一个很特殊的类型;
你可以试试使用StringBuilder哟。
你可以试试使用StringBuilder哟。
#5
这两句:
a=b;
b=c;
等于:
a=new string("b"); //分配了别的地址空间
b=new string("a");
的确这里的a和b和main方法中的a和b指向的不是同一个地址,所以才不会有变化.
a=b;
b=c;
等于:
a=new string("b"); //分配了别的地址空间
b=new string("a");
的确这里的a和b和main方法中的a和b指向的不是同一个地址,所以才不会有变化.
#6
有些东西不需要完全理解,带着问题继续学习,总有一天你会恍然大悟
揭帖把
揭帖把
#7
还是希望能有更全面的了解
#8
string a = "abc";
string b = a; // 这里a和b不是指向同一个对象的,像楼上说的,已经为b分配的新的空间
上面等同 string b = new string(a);
string b = a; // 这里a和b不是指向同一个对象的,像楼上说的,已经为b分配的新的空间
上面等同 string b = new string(a);
#9
对于MySwap(string a, string b)函数,传给函数的实参是对象的引用(指针),
这个引用将按照值传递的方式来进行提供给函数使用,
也就是说,调用函数时首先生成一个引用a和b的副本,
然后函数内部的操作都是对这个副本的操作,
所以原来的a和b并没有改变。
这个引用将按照值传递的方式来进行提供给函数使用,
也就是说,调用函数时首先生成一个引用a和b的副本,
然后函数内部的操作都是对这个副本的操作,
所以原来的a和b并没有改变。
#10
建议楼主看看下面这个帖子:
http://community.csdn.net/Expert/topic/4292/4292562.xml?temp=8.930606E-02
http://community.csdn.net/Expert/topic/4292/4292562.xml?temp=8.930606E-02
#11
字符串是很特殊的
看看这个:
string a = "hello";
string b = "h";
b += "ello"; // append to b
Console.WriteLine( a == b ); // output: True -- same value
Console.WriteLine( (object)a == b ); // False -- different objects
看看这个:
string a = "hello";
string b = "h";
b += "ello"; // append to b
Console.WriteLine( a == b ); // output: True -- same value
Console.WriteLine( (object)a == b ); // False -- different objects
#12
不加ref和out的参数的确是值传递的。
#13
TO lmtz(忽隐忽现)
不赞成你的说法,他传递的是引用也就是指针不是所谓的副本,只是在函数内部重新分配了指针的空间使他指向了常量(一切以“”的字符串都是常量)而REF传的却是指针的指针,我想学过C++的人会明白我所说的。
不赞成你的说法,他传递的是引用也就是指针不是所谓的副本,只是在函数内部重新分配了指针的空间使他指向了常量(一切以“”的字符串都是常量)而REF传的却是指针的指针,我想学过C++的人会明白我所说的。
#14
想明白这些东东,建议去看.net本质论和一些关于指针的书籍(c++ primer 和 inside c++ object)上都有讲到
#15
不赞成你的说法,他传递的是引用也就是指针不是所谓的副本,只是在函数内部重新分配了指针的空间使他指向了常量(一切以“”的字符串都是常量)而REF传的却是指针的指针,我想学过C++的人会明白我所说的。
不仅仅字符串才是常量,引用类型的“常量”很多。你这样等于把字符串特殊化,事实上这是非常正常的,任何引用类型都是这样,即便不是“常量”。
不仅仅字符串才是常量,引用类型的“常量”很多。你这样等于把字符串特殊化,事实上这是非常正常的,任何引用类型都是这样,即便不是“常量”。
#16
using System;
public class MyClass
{
public static void Main()
{
MyClass zlp = new MyClass();
zlp.MySwap("aaa","bbb");
}
void MySwap(string a, string b)
{
string c;
c=a;
a=b;
b=c;
Console.WriteLine(a);
Console.WriteLine(b);
}
}
public class MyClass
{
public static void Main()
{
MyClass zlp = new MyClass();
zlp.MySwap("aaa","bbb");
}
void MySwap(string a, string b)
{
string c;
c=a;
a=b;
b=c;
Console.WriteLine(a);
Console.WriteLine(b);
}
}
#17
按值传递 != 值类型
按引用(地址)传递 != 引用类型
private void button1_Click(object sender, System.EventArgs e)
{
classOne a = new classOne("a");
a.i = 100;
classOne b = new classOne("b");
MySwap(a, b);
MessageBox.Show(a.str);
MessageBox.Show(a.i.ToString());
}
private void MySwap(classOne a, classOne b)
{
classOne c;
c=a;
a=b;
b=c;
MessageBox.Show(a.str);
MessageBox.Show(a.i.ToString());
}
public class classOne
{
public classOne(string s)
{
str = s;
}
public string str = "";
public int i = 0;
}
++++++++++++++++++++++++++++++++++++++++++++++++++++++++
private void button1_Click(object sender, System.EventArgs e)
{
classOne a = new classOne("a");
a.i = 100;
classOne b = new classOne("b");
MySwap(ref a, b);
MessageBox.Show(a.str);
MessageBox.Show(a.i.ToString());
}
private void MySwap(ref classOne a, classOne b)
{
classOne c;
c=a;
a=b;
b=c;
MessageBox.Show(a.str);
MessageBox.Show(a.i.ToString());
}
public class classOne
{
public classOne(string s)
{
str = s;
}
public string str = "";
public int i = 0;
}
按引用(地址)传递 != 引用类型
private void button1_Click(object sender, System.EventArgs e)
{
classOne a = new classOne("a");
a.i = 100;
classOne b = new classOne("b");
MySwap(a, b);
MessageBox.Show(a.str);
MessageBox.Show(a.i.ToString());
}
private void MySwap(classOne a, classOne b)
{
classOne c;
c=a;
a=b;
b=c;
MessageBox.Show(a.str);
MessageBox.Show(a.i.ToString());
}
public class classOne
{
public classOne(string s)
{
str = s;
}
public string str = "";
public int i = 0;
}
++++++++++++++++++++++++++++++++++++++++++++++++++++++++
private void button1_Click(object sender, System.EventArgs e)
{
classOne a = new classOne("a");
a.i = 100;
classOne b = new classOne("b");
MySwap(ref a, b);
MessageBox.Show(a.str);
MessageBox.Show(a.i.ToString());
}
private void MySwap(ref classOne a, classOne b)
{
classOne c;
c=a;
a=b;
b=c;
MessageBox.Show(a.str);
MessageBox.Show(a.i.ToString());
}
public class classOne
{
public classOne(string s)
{
str = s;
}
public string str = "";
public int i = 0;
}
#18
关于值类型的两种传递方法我想就不用举例了
以上是个人观点,欢迎拍转
以上是个人观点,欢迎拍转
#19
----------------------------------------
回复人: ravelin() ( ) 信誉:100 2005-09-29 09:37:00 得分: 0
string 是引用类型,
但 string 对象保留在堆上,不是堆栈上,
所以,当把一个字符串变量赋给另一个字符串变量时,会得到对内存中同一个字符串的两个引用
----------------------------------------
这就是标准答案,现在你不会理解的,记住就可以了,以后你就明白了
回复人: ravelin() ( ) 信誉:100 2005-09-29 09:37:00 得分: 0
string 是引用类型,
但 string 对象保留在堆上,不是堆栈上,
所以,当把一个字符串变量赋给另一个字符串变量时,会得到对内存中同一个字符串的两个引用
----------------------------------------
这就是标准答案,现在你不会理解的,记住就可以了,以后你就明白了
#20
#1
你可以去看我这篇文章:http://blog.csdn.net/tslkfyh/archive/2005/07/13/423889.aspx
字符串是常量,string是引用类型,关键是在MySwap编译器做了一些手脚,在调用前把a,b的MySwap的参数a,b,但在myswap内部又得新给a,b(不是Main中的a,b)重新分配了空间出来后,没引用指向它们,被送往垃圾回收,而Main中的a,b始终没变,也就是我文中所说的,一个是传指针,一个是传指针的指针
字符串是常量,string是引用类型,关键是在MySwap编译器做了一些手脚,在调用前把a,b的MySwap的参数a,b,但在myswap内部又得新给a,b(不是Main中的a,b)重新分配了空间出来后,没引用指向它们,被送往垃圾回收,而Main中的a,b始终没变,也就是我文中所说的,一个是传指针,一个是传指针的指针
#2
string是种很特殊的类型,内部机制确实是引用类型,但使用起来和值类型一样
一句两句说不清的,网上有很多这方面的贴子,自己搜下吧
一句两句说不清的,网上有很多这方面的贴子,自己搜下吧
#3
string 是引用类型,
但 string 对象保留在堆上,不是堆栈上,
所以,当把一个字符串变量赋给另一个字符串变量时,会得到对内存中同一个字符串的两个引用
但 string 对象保留在堆上,不是堆栈上,
所以,当把一个字符串变量赋给另一个字符串变量时,会得到对内存中同一个字符串的两个引用
#4
string是一个很特殊的类型;
你可以试试使用StringBuilder哟。
你可以试试使用StringBuilder哟。
#5
这两句:
a=b;
b=c;
等于:
a=new string("b"); //分配了别的地址空间
b=new string("a");
的确这里的a和b和main方法中的a和b指向的不是同一个地址,所以才不会有变化.
a=b;
b=c;
等于:
a=new string("b"); //分配了别的地址空间
b=new string("a");
的确这里的a和b和main方法中的a和b指向的不是同一个地址,所以才不会有变化.
#6
有些东西不需要完全理解,带着问题继续学习,总有一天你会恍然大悟
揭帖把
揭帖把
#7
还是希望能有更全面的了解
#8
string a = "abc";
string b = a; // 这里a和b不是指向同一个对象的,像楼上说的,已经为b分配的新的空间
上面等同 string b = new string(a);
string b = a; // 这里a和b不是指向同一个对象的,像楼上说的,已经为b分配的新的空间
上面等同 string b = new string(a);
#9
对于MySwap(string a, string b)函数,传给函数的实参是对象的引用(指针),
这个引用将按照值传递的方式来进行提供给函数使用,
也就是说,调用函数时首先生成一个引用a和b的副本,
然后函数内部的操作都是对这个副本的操作,
所以原来的a和b并没有改变。
这个引用将按照值传递的方式来进行提供给函数使用,
也就是说,调用函数时首先生成一个引用a和b的副本,
然后函数内部的操作都是对这个副本的操作,
所以原来的a和b并没有改变。
#10
建议楼主看看下面这个帖子:
http://community.csdn.net/Expert/topic/4292/4292562.xml?temp=8.930606E-02
http://community.csdn.net/Expert/topic/4292/4292562.xml?temp=8.930606E-02
#11
字符串是很特殊的
看看这个:
string a = "hello";
string b = "h";
b += "ello"; // append to b
Console.WriteLine( a == b ); // output: True -- same value
Console.WriteLine( (object)a == b ); // False -- different objects
看看这个:
string a = "hello";
string b = "h";
b += "ello"; // append to b
Console.WriteLine( a == b ); // output: True -- same value
Console.WriteLine( (object)a == b ); // False -- different objects
#12
不加ref和out的参数的确是值传递的。
#13
TO lmtz(忽隐忽现)
不赞成你的说法,他传递的是引用也就是指针不是所谓的副本,只是在函数内部重新分配了指针的空间使他指向了常量(一切以“”的字符串都是常量)而REF传的却是指针的指针,我想学过C++的人会明白我所说的。
不赞成你的说法,他传递的是引用也就是指针不是所谓的副本,只是在函数内部重新分配了指针的空间使他指向了常量(一切以“”的字符串都是常量)而REF传的却是指针的指针,我想学过C++的人会明白我所说的。
#14
想明白这些东东,建议去看.net本质论和一些关于指针的书籍(c++ primer 和 inside c++ object)上都有讲到
#15
不赞成你的说法,他传递的是引用也就是指针不是所谓的副本,只是在函数内部重新分配了指针的空间使他指向了常量(一切以“”的字符串都是常量)而REF传的却是指针的指针,我想学过C++的人会明白我所说的。
不仅仅字符串才是常量,引用类型的“常量”很多。你这样等于把字符串特殊化,事实上这是非常正常的,任何引用类型都是这样,即便不是“常量”。
不仅仅字符串才是常量,引用类型的“常量”很多。你这样等于把字符串特殊化,事实上这是非常正常的,任何引用类型都是这样,即便不是“常量”。
#16
using System;
public class MyClass
{
public static void Main()
{
MyClass zlp = new MyClass();
zlp.MySwap("aaa","bbb");
}
void MySwap(string a, string b)
{
string c;
c=a;
a=b;
b=c;
Console.WriteLine(a);
Console.WriteLine(b);
}
}
public class MyClass
{
public static void Main()
{
MyClass zlp = new MyClass();
zlp.MySwap("aaa","bbb");
}
void MySwap(string a, string b)
{
string c;
c=a;
a=b;
b=c;
Console.WriteLine(a);
Console.WriteLine(b);
}
}
#17
按值传递 != 值类型
按引用(地址)传递 != 引用类型
private void button1_Click(object sender, System.EventArgs e)
{
classOne a = new classOne("a");
a.i = 100;
classOne b = new classOne("b");
MySwap(a, b);
MessageBox.Show(a.str);
MessageBox.Show(a.i.ToString());
}
private void MySwap(classOne a, classOne b)
{
classOne c;
c=a;
a=b;
b=c;
MessageBox.Show(a.str);
MessageBox.Show(a.i.ToString());
}
public class classOne
{
public classOne(string s)
{
str = s;
}
public string str = "";
public int i = 0;
}
++++++++++++++++++++++++++++++++++++++++++++++++++++++++
private void button1_Click(object sender, System.EventArgs e)
{
classOne a = new classOne("a");
a.i = 100;
classOne b = new classOne("b");
MySwap(ref a, b);
MessageBox.Show(a.str);
MessageBox.Show(a.i.ToString());
}
private void MySwap(ref classOne a, classOne b)
{
classOne c;
c=a;
a=b;
b=c;
MessageBox.Show(a.str);
MessageBox.Show(a.i.ToString());
}
public class classOne
{
public classOne(string s)
{
str = s;
}
public string str = "";
public int i = 0;
}
按引用(地址)传递 != 引用类型
private void button1_Click(object sender, System.EventArgs e)
{
classOne a = new classOne("a");
a.i = 100;
classOne b = new classOne("b");
MySwap(a, b);
MessageBox.Show(a.str);
MessageBox.Show(a.i.ToString());
}
private void MySwap(classOne a, classOne b)
{
classOne c;
c=a;
a=b;
b=c;
MessageBox.Show(a.str);
MessageBox.Show(a.i.ToString());
}
public class classOne
{
public classOne(string s)
{
str = s;
}
public string str = "";
public int i = 0;
}
++++++++++++++++++++++++++++++++++++++++++++++++++++++++
private void button1_Click(object sender, System.EventArgs e)
{
classOne a = new classOne("a");
a.i = 100;
classOne b = new classOne("b");
MySwap(ref a, b);
MessageBox.Show(a.str);
MessageBox.Show(a.i.ToString());
}
private void MySwap(ref classOne a, classOne b)
{
classOne c;
c=a;
a=b;
b=c;
MessageBox.Show(a.str);
MessageBox.Show(a.i.ToString());
}
public class classOne
{
public classOne(string s)
{
str = s;
}
public string str = "";
public int i = 0;
}
#18
关于值类型的两种传递方法我想就不用举例了
以上是个人观点,欢迎拍转
以上是个人观点,欢迎拍转
#19
----------------------------------------
回复人: ravelin() ( ) 信誉:100 2005-09-29 09:37:00 得分: 0
string 是引用类型,
但 string 对象保留在堆上,不是堆栈上,
所以,当把一个字符串变量赋给另一个字符串变量时,会得到对内存中同一个字符串的两个引用
----------------------------------------
这就是标准答案,现在你不会理解的,记住就可以了,以后你就明白了
回复人: ravelin() ( ) 信誉:100 2005-09-29 09:37:00 得分: 0
string 是引用类型,
但 string 对象保留在堆上,不是堆栈上,
所以,当把一个字符串变量赋给另一个字符串变量时,会得到对内存中同一个字符串的两个引用
----------------------------------------
这就是标准答案,现在你不会理解的,记住就可以了,以后你就明白了