C语言 函数返回数组和指针区别

1.示例代码

#include <stdio.h>

char * str1()
{
	char A[] = "Hello!";
	return A;
}
char * str2()
{
	char A[] = "Hello!";
	char *p;
	p = A;
	return p;
}
char * str3()
{	
	char A[1024] = "Hello!";
	return A;
}
char * str4()
{
	char A[1024] = "Hello!";
	char *p;	
	p = A;
	return p;
}
char * str5()
{
	char A[1024] = "Hello!";
	char *p;
	A[1018] = 'h';
	A[1019] = 'e';
	A[1020] = 'l';
	A[1021] = 'l';
	A[1022] = 'o';
	A[1023] = '\0';
	p = A;
	p += 1018;
	return p;
}
char * str6()
{
	static char A[1024] = "Hello!";
	char *p;
	A[1018] = 'h';
	A[1019] = 'e';
	A[1020] = 'l';
	A[1021] = 'l';
	A[1022] = 'o';
	A[1023] = '\0';
	p = A;
	p += 1018;
	return p;
}
char * str7()
{
	char *p = "Hello!";
	return p;
}
char * str8()
{
	char A[1024*1009] = "Hello!";
	return A;
}


void main()
{
	printf("str1:%s\n", str1());
	printf("str2:%s\n", str2());
	printf("str3:%s\n", str3());
	printf("str4:%s\n", str4());
	printf("str5:%s\n", str5());
	printf("str6:%s\n", str6());
	printf("str7:%s\n", str7());
	//printf("str8:%s\n", str8());
}

2.运行结果



3.结果分析

  • 函数str1()和str2()返回乱码,这是因为函数运行时函数参数和函数里面的局部变量是存放在栈(stack)中,当函数结束返回时栈也被系统回收,所以返回的数组或者指针所指向的地址数据已经被覆盖,为乱码;
            注:更多了解程序在内存的位置参考:http://blog.csdn.net/hairetz/article/details/4141043#reply
  • 函数str3()和str4()为什么可以正常返回呢,组数在栈中的数据在函数返回时没有被操作系统回收吗?这个问题的答案留在下面回答。
  • 函数str5()中从数组的A[1018]元素到A[1023]元素分开赋值,然后指针P指到数组的A[1018]元素返回,打印结果乱码;
  • 函数str6()与str5()不同之处在于在声明数组A[]的时候加上static关键字,这表明数组中的数据不再存放在内存中的栈而是存放在静态变量区和全局变量放在一个区域,只有在程序运行结束后系统才会回收,所以可以正常返回;
那么为啥函数str3()和str4()可以正常返回数组结果,str5()不可以呢,这是因为,他们三个函数中的数组都存放在内存中的栈中,只是因为数组设置的比较 大为1024,当存放的是小数组“Hello!”时候可以返回是因为内存没有被完全覆盖,而在函数str5()中在数组的后面几个元素被覆盖了,所以输出乱码;这是偶然现象,如果在栈被回收后立马被完全利用,那么函数str3()和函数str4()返回的结果也会是乱码。
  • 为什么函数str7()可以正常返回字符串呢?这是因为声明的字符指针p存放在栈中,而“Hello!”存放在常量区,它在程序运行结束由操作系统回收,而指针p存放的是它的地址,在函数返回时候把它的地址返回给主函数,所以可以正确打印字符串。
  • 函数str8(),在主函数未调用,因为调用程序会出现栈溢出,程序会停止运行,可以看出这里的栈大小大约为1M Byte。

4.如何修改

  那么如何修改成程序使得函数可以返回数组,这里有以下几种方法:
  1.   如上面程序str6()中把数组声明为static 存放在静态变量区,但是这样存在内存泄漏,也可以通过malloc(C语言)或者new(C++)将数组声明在堆(heap)中,
            然后在函数使用完后free()或者delete内存;不过有可能存在在函数外面忘记释放内存的情况;
         2.通过指向数组的指针或者结构实现,参考:http://blog.csdn.net/zouxinfox/article/details/2525206
         3.建议使用把数组作为函数的形参传递进去,在调用函数的主函数声明数组,在使用完后释放数组,参考:http://www.cnblogs.com/yangxi/archive/2011/09/18/2180759.html

5. 思考

 在理解程序在内存中的存储情况,可以方便理解这个问题。
  • 7
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值