关于按值传递和按引用传递(送给这个方面的新手——包括我自己)
2008-07-30 18:27
267 查看
我记得刚上大学我们学院就给我们开了第一门专业课——高级语言程序设计。在函数一节里面,首先要学到形式参数和实际参数,然后就学了按值传递和按引用传递,当时学得那叫一个云里雾里啊,再加上后面还学了个指针,弄得我完全是丈二和尚摸不着头脑……好在我记住了一段话,并把它做为金科玉律,还是让我勉强在编程的时候不会搞出太多错来。
这段话就是:凡是在函数定义里面的形式参数为类类型的,函数调用时实际参数为对象,此时为按引用传递;凡是在函数定义里面的形式参数为值类型的,函数调用时实际参数为值,此时为按值传递。
还好,这句话有些绕口但不是特别绕口。
现如今,我编程再也不用C和C++了(我皈依到Microsoft门下),真正做应用的时候,那些问题我也从来不再考虑,可是前几天同学弄的一个问题着实让我迷糊了半天。
总之,我先把代码写下来吧。在VS中新建一个控制台应用程序,改写其Program.cs文件如下:
Code
0
hello
The int value is 10 and the string value is abcd
----------------------------------------------------------
0
hello
The int value is 11 and the string value is hijk
其实我也先为自己辩解几句,上面这东西迷糊人,Microsoft也有责任,从前在C的年代,哪有string这东西,什么时候我们都用char*,这肯定是个指针。现如今说int是值类型吧,它有个Int32的结构(Java更狠,直接就是Integer的类),说String是个引用吧,它还有个小写的string的关键字。微软让高人方便了,却让像我这样的矬人傻了眼。
不多说,看上面代码。明眼人一看,第一个changeInt(int i)的方法就是狗屁,这显然是按值传递,以前那个i纹丝不动;再看第三个changA(A a),这个方法也没什么,A是我定义的类型,肯定是按引用传递,方法里面改了A的公共字段,外面的A也得跟着改;最后看一下changeString(string s),直说了吧,这个也是按引用传递,在函数里面改了s,白痴问题来了,函数里面改了s,怎么改完了输出不跟着变呢?
其实这段程序纯是骗小孩玩的,不管我传的是个string还是个String,都是一码事,全是按引用传递的。这段代码和那个changeA(A a)的区别就在于,changeA改的是a的公共字段,而changeString改的是s本身。如果我在changeA的第一句添上a=new A();再运行这段代码,就会发现最后一句输出的a和从前的结果是一样的。
说到底,C#和Java说是不用指针,那不可能,没指针哪来的NullReferenceException和NullPointerException啊。对于按引用传递的对象来说,函数在调用的时候,创建了一个新的指针(Java中的pointer、C#中的reference),指向的是那个对象。这个东西存的就是那个对象在内存里的地址,和C里面的指针是一个东东,只是不让+、-而已。然后我们在changeString里把这个地址指向了"world"的内存地址,这里改变的只是新创建出来的那个指针,而原来那个指向"hello"的没跟着变,所以打印语句打出来的还是hello。对于changeA来说,新创建出来的指针指向地址的和Main函数的a指向的是一个地方,由于在changeA里面我们没给它重新定向,所以我改了changeA里面的a,Main函数里面的a也跟着改了。
现在那条金科玉律还是对的了,只不过我要恬不知耻地加上:看吧,如果你用VS来开发程序,对于函数按引用传递的参数来说,如果你改的东西是.出来的,那就改变了函数外面那个对象,如果你把形参拿下来直接后面就放=了,那外面就不改啦,嘿嘿嘿^_^
PS:看客请不要逼问我指针的定义是啥,如果你认为C#里面reference不是指针我也不反对
这段话就是:凡是在函数定义里面的形式参数为类类型的,函数调用时实际参数为对象,此时为按引用传递;凡是在函数定义里面的形式参数为值类型的,函数调用时实际参数为值,此时为按值传递。
还好,这句话有些绕口但不是特别绕口。
现如今,我编程再也不用C和C++了(我皈依到Microsoft门下),真正做应用的时候,那些问题我也从来不再考虑,可是前几天同学弄的一个问题着实让我迷糊了半天。
总之,我先把代码写下来吧。在VS中新建一个控制台应用程序,改写其Program.cs文件如下:
Code
0
hello
The int value is 10 and the string value is abcd
----------------------------------------------------------
0
hello
The int value is 11 and the string value is hijk
其实我也先为自己辩解几句,上面这东西迷糊人,Microsoft也有责任,从前在C的年代,哪有string这东西,什么时候我们都用char*,这肯定是个指针。现如今说int是值类型吧,它有个Int32的结构(Java更狠,直接就是Integer的类),说String是个引用吧,它还有个小写的string的关键字。微软让高人方便了,却让像我这样的矬人傻了眼。
不多说,看上面代码。明眼人一看,第一个changeInt(int i)的方法就是狗屁,这显然是按值传递,以前那个i纹丝不动;再看第三个changA(A a),这个方法也没什么,A是我定义的类型,肯定是按引用传递,方法里面改了A的公共字段,外面的A也得跟着改;最后看一下changeString(string s),直说了吧,这个也是按引用传递,在函数里面改了s,白痴问题来了,函数里面改了s,怎么改完了输出不跟着变呢?
其实这段程序纯是骗小孩玩的,不管我传的是个string还是个String,都是一码事,全是按引用传递的。这段代码和那个changeA(A a)的区别就在于,changeA改的是a的公共字段,而changeString改的是s本身。如果我在changeA的第一句添上a=new A();再运行这段代码,就会发现最后一句输出的a和从前的结果是一样的。
说到底,C#和Java说是不用指针,那不可能,没指针哪来的NullReferenceException和NullPointerException啊。对于按引用传递的对象来说,函数在调用的时候,创建了一个新的指针(Java中的pointer、C#中的reference),指向的是那个对象。这个东西存的就是那个对象在内存里的地址,和C里面的指针是一个东东,只是不让+、-而已。然后我们在changeString里把这个地址指向了"world"的内存地址,这里改变的只是新创建出来的那个指针,而原来那个指向"hello"的没跟着变,所以打印语句打出来的还是hello。对于changeA来说,新创建出来的指针指向地址的和Main函数的a指向的是一个地方,由于在changeA里面我们没给它重新定向,所以我改了changeA里面的a,Main函数里面的a也跟着改了。
现在那条金科玉律还是对的了,只不过我要恬不知耻地加上:看吧,如果你用VS来开发程序,对于函数按引用传递的参数来说,如果你改的东西是.出来的,那就改变了函数外面那个对象,如果你把形参拿下来直接后面就放=了,那外面就不改啦,嘿嘿嘿^_^
PS:看客请不要逼问我指针的定义是啥,如果你认为C#里面reference不是指针我也不反对
相关文章推荐
- 关于 指针的引用和指针值传递
- 关于Python函数参数传递方式--值传递?引用传递!
- 关于参数传递的问题 这个帖子的感想
- 关于Java四种引用包括强引用,软引用,弱引用,虚引用。
- 关于mybatis多对多关联查询 下面的例子让新手看不错。可以改进的一点是 1、不必建立 关联对象实体,可以用map传递两个id进去 2、文章的resultMa
- 关于vbscript 与 javascript如何传递变量(包括服务器端与客户端)
- 关于C++对函数传参与函数返回值进行引用传递的详解
- C++ 中解析关于传值、传地址、传递引用的解析
- 这个是个牛人关于计算机视觉方面。。。做的非常好。。。
- Golang关于channel传递引用引发的坑
- 关于C#值类型,引用类型,值传递,引用传递
- 关于C#的引用参数传递
- 我自己关于 PHP 数组传递的误区
- java中关于参数传递问题的解释(传值与传引用的若干问题的解释)
- 关于C#值类型,引用类型,值传递,引用传递(ref,out)
- 这个帖子介绍了关于structure和及struct arrary 作为参数 传递
- 关于Java中按值传递和按引用传递的问题详解
- 关于JAVA中参数传递问题的总结(按值传递和引用传递)
- 送给所有拥有梦想的人(包括我自己)
- 关于Java的引用和函数参数传递