一个简单问题,关于函数参数传递

时间:2022-08-29 21:19:09
public class MyClass
{
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始终没变,也就是我文中所说的,一个是传指针,一个是传指针的指针

#2


string是种很特殊的类型,内部机制确实是引用类型,但使用起来和值类型一样

一句两句说不清的,网上有很多这方面的贴子,自己搜下吧

#3


string 是引用类型,
但 string 对象保留在堆上,不是堆栈上,
所以,当把一个字符串变量赋给另一个字符串变量时,会得到对内存中同一个字符串的两个引用

#4


string是一个很特殊的类型;

你可以试试使用StringBuilder哟。

#5


这两句:
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);

#9


对于MySwap(string a, string b)函数,传给函数的实参是对象的引用(指针),
这个引用将按照值传递的方式来进行提供给函数使用,
也就是说,调用函数时首先生成一个引用a和b的副本,
然后函数内部的操作都是对这个副本的操作,
所以原来的a和b并没有改变。

#10


建议楼主看看下面这个帖子:

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

#12


不加ref和out的参数的确是值传递的。

#13


TO  lmtz(忽隐忽现)
不赞成你的说法,他传递的是引用也就是指针不是所谓的副本,只是在函数内部重新分配了指针的空间使他指向了常量(一切以“”的字符串都是常量)而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);
}
}

#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;
}

#18


关于值类型的两种传递方法我想就不用举例了


以上是个人观点,欢迎拍转

#19


----------------------------------------
回复人: ravelin() ( ) 信誉:100  2005-09-29 09:37:00  得分: 0  
 
 
   string 是引用类型,
但 string 对象保留在堆上,不是堆栈上,
所以,当把一个字符串变量赋给另一个字符串变量时,会得到对内存中同一个字符串的两个引用
----------------------------------------
这就是标准答案,现在你不会理解的,记住就可以了,以后你就明白了

#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始终没变,也就是我文中所说的,一个是传指针,一个是传指针的指针

#2


string是种很特殊的类型,内部机制确实是引用类型,但使用起来和值类型一样

一句两句说不清的,网上有很多这方面的贴子,自己搜下吧

#3


string 是引用类型,
但 string 对象保留在堆上,不是堆栈上,
所以,当把一个字符串变量赋给另一个字符串变量时,会得到对内存中同一个字符串的两个引用

#4


string是一个很特殊的类型;

你可以试试使用StringBuilder哟。

#5


这两句:
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);

#9


对于MySwap(string a, string b)函数,传给函数的实参是对象的引用(指针),
这个引用将按照值传递的方式来进行提供给函数使用,
也就是说,调用函数时首先生成一个引用a和b的副本,
然后函数内部的操作都是对这个副本的操作,
所以原来的a和b并没有改变。

#10


建议楼主看看下面这个帖子:

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

#12


不加ref和out的参数的确是值传递的。

#13


TO  lmtz(忽隐忽现)
不赞成你的说法,他传递的是引用也就是指针不是所谓的副本,只是在函数内部重新分配了指针的空间使他指向了常量(一切以“”的字符串都是常量)而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);
}
}

#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;
}

#18


关于值类型的两种传递方法我想就不用举例了


以上是个人观点,欢迎拍转

#19


----------------------------------------
回复人: ravelin() ( ) 信誉:100  2005-09-29 09:37:00  得分: 0  
 
 
   string 是引用类型,
但 string 对象保留在堆上,不是堆栈上,
所以,当把一个字符串变量赋给另一个字符串变量时,会得到对内存中同一个字符串的两个引用
----------------------------------------
这就是标准答案,现在你不会理解的,记住就可以了,以后你就明白了

#20