通常我们希望通过函数调用使主调函数能得到一个确定的值,这就是函数的返回值。
函数的返回值是通过函数中的 return 语句获得的。return 语句将被调函数中的一个确定的值带回到主调函数中,供主调函数使用。
一、类型一致
函数的返回值类型是在定义函数时指定的。return 语句中表达式的类型应与定义函数时指定的返回值类型一致。如果不一致,则以函数定义时的返回值类型为准,对 return 语句中表达式的类型自动进行转换,然后再将它返回给主调函数使用。
测试代码:
// 定义类型与实际返回类型一致int test1(){ return 0;}// 定义类型与实际返回类型不同int test2(){ return 1.0;}
运行结果:
警告 C4244 “return”: 从“double”转换到“int”,可能丢失数据
二、多个return
一个函数中可以有多个 return 语句,但并不是所有的 return 语句都起作用。执行到哪个 return 语句,就是哪个 return 语句起作用,该 return 语句后的其他语句就都不会执行了。
测试代码:
int test1(int stat){ if(stat == 0) return 0; else if(stat == 1) return 1; else if(stat == 1) return 1; else return 1;}
三、return如何将值返回给主调函数
被调函数运行结束后系统为被调函数中的局部变量分配的内存空间就会被释放。return 返回的那个值在被调函数运行一结束就被释放掉了,那么它是怎么返回给主调函数的呢?
在执行 return 语句时系统是在内部自动创建了一个临时变量,然后将 return 要返回的那个值赋给这个临时变量。所以当被调函数运行结束后 return 后面的返回值真的就被释放掉了,最后是通过这个临时变量将值返回给主调函数的。
而且定义函数时指定的返回值类型实际上指定的就是这个临时变量的类型。
四、指针作为函数返回值
用指针作为函数返回值时需要注意的一点是,函数运行结束后会销毁在它内部定义的所有局部数据,包括局部变量、局部数组和形式参数,函数返回的指针请尽量不要指向这些数据,C语言没有任何机制来保证这些数据会一直有效,它们在后续使用过程中可能会引发运行时错误。
测试代码:
#include int *func(){ int n = 100; return &n;}int main(){ int *p = func(), n; n = *p; printf("value = %d", n); return 0;}
运行结果:
value = 100
分析:
n 是 func() 内部的局部变量,func() 返回了指向 n 的指针,func() 运行结束后 n 将被销毁,使用 *p 应该获取不到 n 的值。
但是,这里所谓的销毁并不是将局部数据所占用的内存全部抹掉,而是程序放弃对它的使用权限,弃之不理,后面的代码可以随意使用这块内存。如果有其它函数被调用就会覆盖这块内存,得到的数据就失去了意义。
C 语言不支持在调用函数时返回局部变量的地址,除非定义局部变量为 static 变量。
五、函数中返回字符串指针
错误代码:
char* getString(){ char str[20] = "TEST"; return str;}
分析:
理由见第“四”条
正确代码:
char* getString(){ char *p = "TEST"; return p;}
分析:
在函数内部定义了一个指向char类型的指针p,该指针指向一个字符串常量"TEST",而它存放在整个程序的常量区,而并不是局部变量,并不会因为函数调用的结束而消失。
对于指针变量p虽然是一个局部变量,但p本身的值仅仅是一个4个字节的指针地址值。