小议C++中函数的参数的传递

     c++中为每一个函数都维护了一个运行栈(活动记录),这个栈存储了与该函数相关的一系列信息,包括函数中声明的变量,传递给函数的实际参数,以及该函数的返回地址等,使用gdb调试器可以清楚的看到这一切。当调用发生时,该函数会将实际参数的值copy到运行栈,也就是常说的值传递。那么很显然的就是,如果我们在函数中改变的只是实际参数的值的拷贝,所以实际参数的值并没有发生变化。

     那么,如果我们想要去改变实际参数的值,怎么办呢?首先当然会想到指针啦,因为指针实在是太牛了,它可以到处指啊。如果你用熟了指针,可以说你已经是一个c语言的有点高手了。:-),最经典的一个用指针操作实际参数的例子就是交换两个数的值,简直是不想在把它拿出来举例子了,网上百度一下就到处都是,更不用说是谷歌了。还有一种改变实际参数的办法是采用引用参数。最初对引用参数不理解的时候,我就记住一点,引用参数的作用就是给实际参数起了一个别名,它绑定到实际参数上。对引用参数所做的所有的操作,都会作用到实际参数。说的稍微深奥一点就是,引用参数传递的实际是一个变量的左值,什么是左值呢?顾名思义,左值就是可以被赋值的值。一个变量有两个值,一个是左值,一个是右值。左值就是该变量的值在内存单元中的地址,右值就是该变量的值。体会意思就行,这一点说是话,我是不太清楚啊,悲哀。

     另外指针和引用还有一个共同的优点就是它们都可以提高程序的效率。虽然对于参数为简单的变量的函数来说,提高的效率可能杯水车薪,微不足道。但是对于那种参数为巨大的类等的东西,当函数将实际参数的值复制到运行栈的时间代价和空间代价是任何一个真正的程序员所不能容忍的。采用指针和引用时,函数操作的就是实际参数,所以不用将它复制到自己的运行栈。当然,有的哥们会担心如果采用这种方式,我们不小心将实际参数的值改变了,但实际上并不想让实际参数的值改变怎么办?这个不用担心,因为C++的设计者早就想到了这一点,他们引入了const这个关键字(貌似是从c语言继承过来的,那就不是c++设计者的创意啦)。通过用const修饰的指针和引用,使得用户不能够通过这个指针或引用修改它们所指向的内存单元。

     既然指针和引用都有这两个优点,它们两个又有什么区别呢?从表面上看,指针可以不用被初始化,可以为空,可以随便乱指,当然这都是在符合语法规则的前提下。而引用必须被初始化为一个变量,并且永远不允许再改变。另外引用有一个重要的优点就是看着“好看”,又有效率。我说的“好看”,那可是真的好看,比如说,在重载运算符中:

Matrix a,b,c;    //Matrix是个巨大的类
Matrix operator+(const Matrix &m1,const Matrix &m2)
{
      Matrix result;
      //add a and b -> result
     return result;
}

c=a+b   //是不是很好看

但是如果使用指针的话,那可真就是惨不忍睹了:
Matrix a,b,c;    //Matrix是个巨大的类
Matrix operator+(const Matrix *m1,const Matrix *m2)
{
      Matrix result;
      //add m1 and m2 -> result
     return result;
}

c=&a+&b   //是不是很惨啊
&(&a+&b)+&c //这是更惨的

引用还真是个好东西啊。

     当C++的函数传递的参数是个数组时,编译器会将其看作一个指针,也就是数组首元素的地址。编译器不知道数组到底有多少个元素,其实我们最常使用的main函数就已经向我们所名了这个道理,当使用命令行参数的时候,传递的两个参数分别是argc和argv,这个argc就是用来专门告诉编译器参数个数的。连main函数都得这样,其他函数就更不用说了。所以就算你在定义时像这样void sort(int a【10】),但这是没用的,编译器只会将它看成 void sort(int* a)。要想让函数知道数组有几个元素怎么办呢,当然上面个已经说明了一种方法。还有一种方法就是数组引用,呵,又是引用,没错,可以写成这个样子 void sort(int (&a) [10]),就是着个样子,看起来有点变态。但是千万不要把那个(&a)中的括号去掉,否则就真变态了。

     就写到这里吧,该回去了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值