C和C++中的函数参数

来源:互联网 发布:达内大数据百度云盘 编辑:程序博客网 时间:2024/05/04 23:31

        记得在刚学习C语言的时候,老师在解说起函数的参数传递时,将传递方式分成了两种:值传递和地址传递。过去了这么多年,在实际的工作中不可避免的也会用到带参数的函数。忽然觉得地址传递本身也是一种值传递。学过C语言的人都知道,C的变量中有一种特别的变量,叫做指针,它的值是另外一个变量的地址。所谓的地址传递,实际上是将一个指针变量的值传进去。而变量本身的地址并不会随着函数调用进入到函数里面去。比如下面的一段代码:

void printStr(char * p1){     printf("%d\n", &p1);     p1 = new char [40];     sprintf(p1, "%s", "this is a test!\n");     printf("%s", p1);     delete []p1;     p1 = NULL;}int _tmain(int argc, _TCHAR* argv[]){    char *p = new char[20];sprintf(p, "%s", "hello world!");printf("%s\n",p);printf("%d\n", &p);printStr(p);printf("%d\n", &p);if(NULL != p){delete []p;p = NULL;}return 0;}


在main先定义了一个指针变量p,这时候会在栈里面开辟一段空间,用以保存指针p自己的地址,这个空间有4个字节的大小;当使用new char[20]给p分配空间的时候,实际上在堆中连续分配20个字节的空间,然后令p指针指向这段空间。但是变量p自己的地址并不会变化。这时候p的值就是刚才分配的堆空间的首地址。sprintf函数是给p指向的堆空间赋值。再到我们自己定义的printsStr函数,这时候注意传入的参数是p。实际上是将p指向的堆空间的首地址传入到了printStr函数内部,换言之,是将p的值传入了printStr函数。只是,这个值也是一个地址,所以我的老师会说是地址传递。本质上来说也是值传递,因为p自己的地址并没有进入到printStr函数内部。运行上述代码的结果如图示:

由上图知,第一次打印出来的p地址值是:1244884,在printStr函数里面打印出来的p1地址是1244648,调用完printfStr后,再打印p的地址,还是1244884,说明p自身的地址并没有发生变化。传入到printStr之后,实际上是系统另外生成一个变量,然后将p的值赋给了p1而已,在函数里面对p1地址的操作,完全不影响p本身,本质上来说,还是值传递。

在C++中,参数传递增加了一种类型,引用。什么是引用呢?引用是变量的一个别名。定义引用的时候,必须初始化,因为引用本身并不占内存空间,不会在内存中为引用变量重新赋值,只是标明该变量是个引用类型,如果它的值在定义的时候不确定,在后面就没办法赋值,因为它不占内存空间,没地方保存值。在函数里面传递引用参数,实际上是将原参数自己传递了过去。这样的好处就是封装了地址,相对较安全。
原创粉丝点击