功能描述:在给上大一的表妹讲一个C语言编程简单的知识点的时候踩雷了,是一届简单的字符串复制的功能,函数的返回值为char *类型,记录一下这个知识点的踩坑过程,对于C语言学习的新手可能会场贩的错误,老手请略过。
参考资料:【c语言中返回值为char*的情况分析】
1. 错误的例子
首先给出一个典型的错误的例子:
/*想实现字符串复制,返回*/
char* func_strCopy(char* name){
char str[5];
strcpy(str, name);
return str;
}
// 函数调用
char str_test[6] = { 'c', 'h', 'i', 'n', 'a' , '\0' };
char *str_test = "china"; //两种变量都可以
char *dj = func_strCopy(str_test);
printf("dj=%s", dj);
2.错误分析
错误分析:在 func_strCopy()
函数中,将 name 中的内容拷贝到 str 中,并返回了 str 的地址,返回值类型是 char * 类型,但是 由于 str 是个局部变量,局部变量存储在栈中,函数运行完之后,内存被释放了,因此 char *dj = func_strCopy(str_test); dj 接收到的地址是错的,因此无法实现字符串复制的功能。
因此以上函数在编译过程中可能会提示 warning, 返回局部变量或临时变量的地址,这是一定不能忽视的。
3.错误解决
解决,从 func_strCopy()
函数入手,有以下几种方式:
- 将 str 数组定义为 static 变量,即
static char str[5];
- 将 str 定义为静态常量,此时变量存储在常量区。即,
char *str= “hello”;
- 将 str 改为动态数组,即,
char *str= (char*)malloc(5*sizeof(char));
- 将 str[10]数组定义为全局变量。
总结:通过以上方式,返回字符串的首地址,可完成字符串复制的功能。总结为, 函数返回值为指针时,不能返回函数内部局部变量的地址,因为函数内部的局部变量在函数运行结束后即被释放了。
4.解决过程分析
下面解释一下以上的方法:
首先,普及知识:全局变量,static 局部变量,static 全局变量都存储在静态存储区;局部变量在栈分配空间,使用完之后,由系统自动释放。
关于 静态局部变量和全局变量的区别,参考资料为:【静态局部变量和全局变量的区别!】,关于各种变量的存储区域,参考文章:【C语言内存区域划分】
static 变量存在静态数据存储区,它只被初始化一次,从第一次初始化到程序结束一直存在,在下一次调用时还可以保持原来的值。
static 局部和全局变量的区别是,static 局部变量作用域为函数内部,而static 全局变量的作用域为整个文件。
static 全局变量和普通全局变量区别:作用域不同,static 全局变量只能被本文件访问,而普通全局变量可以被其他文件访问
- 数组定义为 static 变量后,返回static变量的地址,函数执行完,地址不会被释放,因此调用函数可以接收到这个变量的地址
- 理由同上
- 使用 malloc 动态分配的内存,存储在堆上,在 free 该段内存之前,一直保持该段内存
- 定义为全局变量,理由同1