c# 中值传递与引用传递的一个问题

Caramel_Geass 2016-07-12 11:12:33
各位大大大家好,c#新人对于值传递和引用传递一直心存疑问,看了http://www.cnblogs.com/kirinboy/archive/2012/06/15/value-and-reference-in-csharp-2.html感觉清晰了不少,但是继续学习到数组排序的时候又产生了新的问题。

冒泡排序代码如下:
 class Program
{
static void Main(string[] args)
{
int[] a = { 2, 6, 4, 8, 10, 12, 89, 68, 45, 37 };
string output = "The original order is : ";
for (int i = 0; i < a.Length; i++)
output += a[i] + " ";
Console.WriteLine(output += "\n");

BubbleSort(a);

output = "The new order is : ";
for (int i = 0; i < a.Length; i++)
output += a[i] + " ";
Console.WriteLine(output);
}

static void BubbleSort(int[] b)
{
for (int pass = 1; pass < b.Length; pass++)
for (int i = 0; i < b.Length - 1; i++)
if (b[i] > b[i + 1])
Swap(b, i);
}

static void Swap (int[] c, int d)
{
int hold;
hold = c[d];
c[d] = c[d + 1];
c[d + 1] = hold;
}
}


我的问题在于,对于c#,默认的传递型式为值传递,那么这段代码中的Swap方法应该也是值传递吧?这样的话按照开头那篇帖子的说法,难到不是计算机在内存中新开辟一块内存保存局部变量c[i]的各个值么?为什么这段代码看上去是直接改变了原数组的各个变量呢?是因为数组有什么特殊的性质么?

新手还在学习中,可能问题表述不够清楚,还望海涵。
...全文
230 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
在 c++ 中,它真的会去拷贝整个对象、然后放入过程参数堆栈。因此在c++中如果你不小心地到处去写空间释放代码,就会到处发生意想不到的内存泄漏故障。 在 .net 中,永远不会去拷贝引用对象的副本内容,不论你按值传递还是按引用传递,都是传引用。
  • 打赏
  • 举报
回复
static void Swap (int[] c, int d) 与 static void Swap (ref int[] c, int d) 的区别只在于这个方法结束时是否要把堆栈弹出的引用重新赋值给变量c。不论按值传递还是按引用传递,实际上传递的c都是一个引用。 实际上.net的“按值传递”与“按引用传递”这个说法是从c继承来的,是有误导性的,按说.net应该重新起一个名字(如果不是15年前i,我想它会重新命名的)。要注意跟c/c++区分开来。
  • 打赏
  • 举报
回复
.net 中所谓的值传递,是 .net 的值传递。有些人套用 c/c++ 的说法,那是错误的。 以值传递方式方式传递参数 int[] c,这个意思就是把 c 这个引用(或者也可以隐喻地说成是“指针”)作为值而传递。而一些只是学过一点 c 语言不知道什么入门书的人则说“是把c在堆栈中复制了一份而传递”这是完全错误的。 在 .net 中,值传递比引用传递更快。而在c中,引用传递通常比值传递更快。.net跟标准c完全是两个不同的东西,不能胡乱生搬硬套。 在.net中,所谓“按值传递”,是说传递过去的引用地址c,在方法 Swap 结束时(堆栈弹出时)直接被丢弃了,而不会用堆栈弹出的新的引用来重新赋值给变量c。而“按引用传递”,就是说在 Swap 从堆栈弹出新的引用之后把引用重新赋值给变量c,从而c的引用就改变了。 因此在 .net 中,按值传递比按引用传递更快。
xuzuning 2016-07-12
  • 打赏
  • 举报
回复
你的问题在于 对于c#,默认的传递型式为值传递 这是谁告诉你的? 如果是你自己,那就是你想当然了 如果是老师告诉你的,那就得打老师的屁股 错误的前提,是推导不出正确的结论的 对于c#,对于 值类型 默认的传递型式为值传递,对于 引用类型 默认的传递型式为引用传递 由于数组是 引用类型,所以你的疑惑就不存在了 至于是否是 在内存中新开辟一块内存保存局部变量c[i]的各个值 是不需要你去过问的(尤其是初学者) 你去学开汽车,也需要先去知道汽车是如何制造出来的吗?
Poopaye 2016-07-12
  • 打赏
  • 举报
回复
引用 楼主 Caramel_Geass 的回复:
对于c#,默认的传递型式为值传递
错误,只有valuetype的子类是值传递,其他都是引用传递
正怒月神 2016-07-12
  • 打赏
  • 举报
回复
数组是引用类型
巴士上的邂逅 2016-07-12
  • 打赏
  • 举报
回复
数组是引用类型
Caramel_Geass 2016-07-12
  • 打赏
  • 举报
回复
引用 6 楼 sp1234 的回复:
static void Swap (int[] c, int d) 与 static void Swap (ref int[] c, int d) 的区别只在于这个方法结束时是否要把堆栈弹出的引用重新赋值给变量c。不论按值传递还是按引用传递,实际上传递的c都是一个引用。 实际上.net的“按值传递”与“按引用传递”这个说法是从c继承来的,是有误导性的,按说.net应该重新起一个名字(如果不是15年前i,我想它会重新命名的)。要注意跟c/c++区分开来。
非常详尽!十分感谢!!
Caramel_Geass 2016-07-12
  • 打赏
  • 举报
回复
引用 4 楼 xuzuning 的回复:
你的问题在于 对于c#,默认的传递型式为值传递 这是谁告诉你的? 如果是你自己,那就是你想当然了 如果是老师告诉你的,那就得打老师的屁股 错误的前提,是推导不出正确的结论的 对于c#,对于 值类型 默认的传递型式为值传递,对于 引用类型 默认的传递型式为引用传递 由于数组是 引用类型,所以你的疑惑就不存在了 至于是否是 在内存中新开辟一块内存保存局部变量c[i]的各个值 是不需要你去过问的(尤其是初学者) 你去学开汽车,也需要先去知道汽车是如何制造出来的吗?
是我的问题没有表述清楚,我的问题在于不知道数组是引用类型现在了解啦
Caramel_Geass 2016-07-12
  • 打赏
  • 举报
回复
引用 1 楼 yuankaiwsl 的回复:
数组是引用类型
原来是这样,这就明白了,感谢

111,125

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Creator Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧