Summary of function parameter
2004-07-14 02:33 FantasySoft 阅读(3305) 评论(4) 编辑 收藏 举报
对C++这位入得厨房,出得厅堂的MM说爱你说了好几年,却从来没有为她真正献出我的真心;当我看到C#那青春而诱人的身段的时候,我毫不犹豫的拜倒在她裙角下,而狂热的关系仅通过ASP.NET 维系了几个月;花心的我随后跟如斯佳丽般简约唯美的Java度过了半年多疯狂开发的光阴。
身心疲惫的我重新回到了C++的怀抱,我发现她竟然是那样的Attractive,那样的风华绝代。我会好好爱她的,当然我是不会忘记我的两位情人的。嘿嘿~~~
请大家原谅我说这样的文绉绉的话,我实在太爱她们了。 好,该言归正传了。
以下是对C++,Java和C#中函数参数的几点总结:
1. Java函数参数的传递都是传值的;
2. 而在C#当中,默认的情况下是传值的,而使用了out或者是ref关键字则可以传递引用;
3. 在C++ 中,可以传值,可以传引用,还可以传递指针。
从三种语言出现的先后顺序以及她们各自对于函数参数传递的设计,我们或多或少可以体味出一些演变的味道。
C++诞生得最早,自然也最为灵活,给予了程序员最大的思考空间,然而也正是这样的灵活令C++成为了一把双刃剑,杀退敌人的同时,也可能伤了自己;等到Java横空出世的时候,把指针搁在了一边,连参数传递的方式都只剩下了Pass By Value。这样的设计确实使得编写程序更为简单而程序本身更为健壮,但是一些问题就不太好处理了,下面就会看到一个例子;接着就是我的偶像Anders创造了C#,在我看来,出自世界上最好的程序员之手的C#确实在灵活和简单之间找到了最佳平衡点。在C#中,再次出现了大家熟悉的Pass By Reference,只是&变成了ref。
C++ :
#include <iostream>
![](/Images/OutliningIndicators/None.gif)
using namespace std;
![](/Images/OutliningIndicators/None.gif)
void swap(int& a, int& b)
{
int t = a;
a = b;
b = t;
}
![](/Images/OutliningIndicators/None.gif)
void swapByPointer(int* a, int* b)
{
int t = *a;
*a = *b ;
*b = t;
}
void main()
{
int a = 5;
int b = 7;
cout << a << " " << b << endl;
swap(a,b);
cout << a << " " << b << endl;
swapByPointer(&a, &b);
cout << a << " " << b << endl;
} C# :
using System;
![](/Images/OutliningIndicators/None.gif)
class MainApp{
public static void Main(){
int i = 5;
int j = 7;
Console.WriteLine("i=" + i + "j=" + j);
swap(ref i, ref j);
Console.WriteLine("i=" + i + "j=" + j);
}
public static void swap(ref int i, ref int j){
int t = i;
i = j;
j = t;
}
}
public class SwapInteger {
public static void main(String[] args)
{
IntegerHolder holder1 = new IntegerHolder();
IntegerHolder holder2 = new IntegerHolder();
holder1.i = 5;
holder2.i = 7;
System.out.println("Holder1 = " + holder1.i);
System.out.println("Holder2 = " + holder2.i);
swap(holder1, holder2);
System.out.println("Holder1 = " + holder1.i);
System.out.println("Holder2 = " + holder2.i);
}
public static void swap(IntegerHolder holder1, IntegerHolder holder2)
{
int i = holder1.i;
holder1.i = holder2.i;
holder2.i = i;
}
static class IntegerHolder
{
public int i;
}
}
对于隐式引用传递,我想再罗嗦几句。因为在Java中,所有的对象都是通过引用来处理的。
譬如,
IntergerHolder holder1 = new IntegerHolder();
通过new关键字创建了一个类IntegerHolder的实例,而Holder1并不是这个实例的本身,它是这个对象实例的引用(Reference);当一个对象引用作为参数传递的时候,传递的是引用本身的一个copy(即是传值),但是对于对象实例而言,确实传递了引用,因此对象属性的控制权就交到了被调函数手上了,你自然就可以在函数体内任意修改对象的属性了。
罗嗦老半天了,还请耐心看完这篇Blog的高手们多多指教。
身心疲惫的我重新回到了C++的怀抱,我发现她竟然是那样的Attractive,那样的风华绝代。我会好好爱她的,当然我是不会忘记我的两位情人的。嘿嘿~~~
请大家原谅我说这样的文绉绉的话,我实在太爱她们了。 好,该言归正传了。
以下是对C++,Java和C#中函数参数的几点总结:
1. Java函数参数的传递都是传值的;
2. 而在C#当中,默认的情况下是传值的,而使用了out或者是ref关键字则可以传递引用;
3. 在C++ 中,可以传值,可以传引用,还可以传递指针。
从三种语言出现的先后顺序以及她们各自对于函数参数传递的设计,我们或多或少可以体味出一些演变的味道。
C++诞生得最早,自然也最为灵活,给予了程序员最大的思考空间,然而也正是这样的灵活令C++成为了一把双刃剑,杀退敌人的同时,也可能伤了自己;等到Java横空出世的时候,把指针搁在了一边,连参数传递的方式都只剩下了Pass By Value。这样的设计确实使得编写程序更为简单而程序本身更为健壮,但是一些问题就不太好处理了,下面就会看到一个例子;接着就是我的偶像Anders创造了C#,在我看来,出自世界上最好的程序员之手的C#确实在灵活和简单之间找到了最佳平衡点。在C#中,再次出现了大家熟悉的Pass By Reference,只是&变成了ref。
C++ :
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedBlockEnd.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedBlockEnd.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedBlockEnd.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
![](/Images/OutliningIndicators/ExpandedBlockEnd.gif)
大家会发现C#和C++之间在Pass By Reference上是十分相似的,只是在C#中必须显式的说明传递的是引用还是值。
在Java中想实现如上的交换两个整数的函数,则由于Java参数传递方式的限制,不得不使用变通的方法了,即使用所谓的Holder类。因为只有通过对象才能实现隐式的引用传递。
Java :
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
![](/Images/OutliningIndicators/ExpandedBlockEnd.gif)
![](/Images/OutliningIndicators/None.gif)
譬如,
IntergerHolder holder1 = new IntegerHolder();
通过new关键字创建了一个类IntegerHolder的实例,而Holder1并不是这个实例的本身,它是这个对象实例的引用(Reference);当一个对象引用作为参数传递的时候,传递的是引用本身的一个copy(即是传值),但是对于对象实例而言,确实传递了引用,因此对象属性的控制权就交到了被调函数手上了,你自然就可以在函数体内任意修改对象的属性了。
罗嗦老半天了,还请耐心看完这篇Blog的高手们多多指教。