对象作为返回值
编译器会将函数栈中的返回值数据拷贝到返回栈中
指针作为返回值
函数的返回值可以是存储某种类型数据的内存地址,称这种函数为指针函数。它们的一般定义形式如下: 类型标识符 *函数名(参数列表); 在C++中,除了内存分配失败之外,new不会返回空指针,并且没有任何对象的地址为零。指针所指向的对象的生存期不应低于该指针的生存期。
用指针作为函数返回值时需要注意的一点是,函数运行结束后会销毁在它内部定义的所有局部数据,包括局部变量、局部数组和形式参数,函数返回的指针请尽量不要指向这些数据,C语言没有任何机制来保证这些数据会一直有效,它们在后续使用过程中可能会引发运行时错误。
#include <stdio.h> int *func(){ int n = 100; return &n; } int main(){ int *p = func(), n; n = *p; printf("value = %d\n", n); return 0; }
运行结果:
value = 100
既然func函数执行结束,那么func()函数内的局部变量就应该被销毁,但是这里可以取到值,这个就很奇怪,修改一下
#include <stdio.h> int *func(){ int n = 100; return &n; } int main(){ int *p = func(), n; printf("c.biancheng.net\n"); n = *p; printf("value = %d\n", n); return 0; }
运行结果:
c.biancheng.net
value = -2
前面说函数运行结束后会销毁所有的局部数据,这个观点并没错,大部分C语言教材也都强调了这一点。但是,这里所谓的销毁并不是将局部数据所占用的内存全部抹掉,而是程序放弃对它的使用权限,弃之不理,后面的代码可以随意使用这块内存。对于上面的两个例子,func() 运行结束后 n 的内存依然保持原样,值还是 100,如果使用及时也能够得到正确的数据,如果有其它函数被调用就会覆盖这块内存,得到的数据就失去了意义。
引用作为返回值
函数返回引用,要求在传参里必须有引用或者指针类型作为被返回的值。
传参用引用
#include <stdio.h> #include <stdlib.h> int func(int& t) { return t; } int main(int argc, char * argv[]) { int a=0; int b=func(a); printf("&a=0X%08X,&b=%08X\n",&a,&b); printf("a=%d, b=%d", &a, &b); printf("a=%d, b=%d", a, b); return 0; } 输出: &a=0X0022FF4C,&b=0022FF48 //十六进制变量地址 a=2293580, b=2293576; //十进制变量地址 a=0, b=0 //变量值
函数返回值和传参都用引用
#include <stdio.h> #include <stdlib.h> int &func(int& t) { return t; } int main(int argc, char * argv[]) { int a=0; int b=func(a); printf("&a=0X%08X,&b=%08X\n",&a,&b); printf("a=%d, b=%d", a, b); return 0; } 输出是: &a=0X0022FF4C,&b=0022FF48 a=0, b=0
函数返回值用引用,传参用指针
#include <stdio.h> #include <stdlib.h> int &func(int* t) { return *t; } int main(int argc, char * argv[]) { int a=0; int b=func(&a); printf("&a=0X%08X,&b=%08X\n",&a,&b); printf("a=%d, b=%d", a, b); return 0; } 输出: &a=0X0022FF4C,&b=0022FF48 a=0, b=0