自定义函数的返回值
根据逻辑需求,需要什么类型的返回值,直接设置即可
这里我们主要探讨一下返回类型是指针的自定义函数
问题描述
今天在牛客网上做题,发现了返回类型是指针的函数需要注意的几个地方
我们先看看返回类型是指针的自定义函数
#include <stdio.h>
char* fun()
{
char str[] = "Hello world!";
return str;
}
int main()
{
char* p;
p = fun();
printf("%s", p);
return 0;
}
分析上述代码
因为是例子,所以就比较简单。看到代码,首先分析逻辑结构,通过 fun() 函数的作用返回str数组的首元素的地址,之后用指针p接受,打印数组。
运行结果
为什么打印出来是乱码呢?
再去分析代码,我们一开始创建了一个局部变量p,p的类型char类型的指针,之后通过调用fun函数,对指针p进行初始化,再打印p里面的值。
通过分析,我们可以大致得到问题就出现在fun函数里面
,fun函数的功能就是返回一个已经初始化结束的字符数组的地址,所以问题就出现在fun函数的返回值。
问题原因:在fun函数里面我们创建了一个char类型的数组,通过返回这个数组的地址,实现功能。但是,在函数里面直接定义的变量属于局部变量(未加static声明的局部变量),局部变量存储在栈区,局部变量在出了函数作用域之后就会被销毁。因此对于上述代码来说,str[]数组是局部变量,fun函数结束后str[]就会被销毁,但是这个地址还在,地址里面却没有任何东西,因此在打印的时候电脑会自动给任意值。
上述代码的修改方法:
法一:
char* fun()
{
char* str = "Hello world!";
return str;
}
int main()
{
char* p;
p = fun();
printf("%s", p);
return 0;
}
注意:上述代码中str还是在栈区存储着,但是Hello world! 存储在文字常量区,常量字符串就是放在这里的, 程序结束后由系统释放。所以fun结束后,Hello world!仍然在文字常量区存储着,通过fun函数,把字符串的首地址传递给主调函数。所以就与局部变量str销毁就没关系了。
法二:
#include <stdio.h>
#include <malloc.h>
#include <string.h>
char* fun()
{
char* str = (char*)malloc(sizeof(char) * 20);
strcpy(str, "Hello world!");
return str;
}
int main()
{
char* p;
p = fun();
printf("%s", p);
free(p);
return 0;
}
注意:上述代码中str分配得来的20字节空间是在堆区开辟的,因此在fun结束后str的空间还存在。
练一下吧:
#include <stdio.h>
char* replaceSpace(char* s) {
}
int main()
{
char s[] = "We Are Happy";
printf("%s", replaceSpace(s));
return 0;
}
题解
#include <stdio.h>
char* replaceSpace(char* s)
{
//保存一份s,避免后面s使用改变
char* temp = s;
//计算有多少个空格
int count = 0;
while (*s)
{
if (*s == ' ')
count++;
s++;
}
//malloc开辟空间
char* s1 = (char*)malloc(sizeof(char)*(s - temp - count + (count * 3) + 1));
int i = 0;
while (*temp)
{
if (*temp != ' ')
{
s1[i] = *(temp);
i++;
temp++;
}
else
{
s1[i] = '%';
s1[i + 1] = '2';
s1[i + 2] = '0';
i += 3;
temp++;
}
}
s1[i] = '\0';
return s1;
}
int main()
{
char s[] = "We Are Happy";
printf("%s", replaceSpace(s));
return 0;
}
但是为什么没有显示任何结果呢?我们调试一下看看
发现malloc出来的空间竟然不能访问!检查代码发现,原来是没有添加malloc函数的头文件。
完整代码
#include <stdio.h>
#include <malloc.h>
char* replaceSpace(char* s)
{
//保存一份s,避免后面s使用改变
char* temp = s;
//计算有多少个空格
int count = 0;
while (*s)
{
if (*s == ' ')
count++;
s++;
}
//malloc开辟空间
char* s1 = (char*)malloc(sizeof(char)*(s - temp - count + (count * 3) + 1));
int i = 0;
while (*temp)
{
if (*temp != ' ')
{
s1[i] = *(temp);
i++;
temp++;
}
else
{
s1[i] = '%';
s1[i + 1] = '2';
s1[i + 2] = '0';
i += 3;
temp++;
}
}
s1[i] = '\0';
return s1;
}
int main()
{
char s[] = "We Are Happy";
printf("%s", replaceSpace(s));
free(replaceSpace(s));
return 0;
}