C++中关于两个函数的区别引出的各种C++特性或是机理

int * Fun(int ival)
{
	int i = ival;
	return &i;
}
        int * Fun(int ival);  //声明
	int val = 5;
	int *ptr = Fun(val);
	cout<<"*ptr = "<<*ptr<<endl;  这段代码是在主函数中的

今天在CSDN上偶尔看到一篇帖子,本来想回复的,可是由于太久远了,帖子早已结,当中自己也想到了很多,也为了写这篇博客百度了一些知识。

两个函数如下:

char * Fun1()
{
	char *string = "helloworld";
	return string;
}
char * Fun2()
{
	char string[] = "helloworld";
	return string;
}

	cout<<"Fun2()返回的地址 = "<<Fun2()<<endl;
	cout<<"Fun1()返回的地址 = "<<Fun1()<<endl;
	cout<<"第一个字符:"<<*Fun2()<<endl;
	cout<<"第二个字符:"<<*(Fun2()+1)<<endl;
	cout<<"第三个字符:"<<*(Fun2()+2)<<endl;

一:

1:这是两个指针函数(函数返回值为一个指针),并且是char类型的。

2:用字符串去初始化一个指针时,这个字符串被作为一个常量存在常量区。

在Fun1()中的字符串是被作为常量存放在常量区的,全程序上下只有一份,而string指针的是在栈区的,所以可以概括为在栈区有一个指向常量区特定空间的指针。

这个string 指针是在函数内部定义的自动变量,所以在Fun1()执行到return的时候,把这个指针的值复制到一个匿名空间内,而Fun1()的string 则随着函数的调用结束而结束生命。

在第二条输出语句执行的时候其实输出的是一个匿名变量,这个变量是由Fun1()返回出来的指针,在Fun1()赶回string之后,位于栈区的string指针就被销毁了。在C++中可以通过一个指针一次性的输出一个连续空间中的值,这是在C语言中没有的。

3:再来看Fun2(),这里用字符串初始化一个字符数组,这里的字符串却是被当做局部变量存放在栈区的,当Fun2()函数调用结束,这个字符串被释放掉,所以第一句输出的是乱码,因为Fun2()返回的是一个未知的指向。另外在Fun2()中string被当做是一个数组的,在返回的过程中,要涉及到数组的复制,然而C/C++是不支持数组的复制的,除非使用strcopy()函数。

4:但是我不理解的是,为什么最后三个输出语句会是有结果的呢?而且还是正确的结果啊,通过Fun2()返回的指针既然已经是无效的了,怎么会输出正确的结果呢?很奇怪啊。说到这里再看下面的代码:

int * Fun(int ival)
{
	int i = ival;
	return &i;
}
        int * Fun(int ival);  //声明
	int val = 5;
	int *ptr = Fun(val);
	cout<<"*ptr = "<<*ptr<<endl;  这段代码是在主函数中的
对上面函数的分析:在主函数中有一个变量val初始化为5,把这个val当做是参数传递给函数Fun(val),在函数传递的过程中,函数栈里的局部变量ival接受了实参val的值,也就是现在的ival也是5了。然后再函数里又定义了一个局部变量i,i接受了ival的值,现在把i的地址返回出去。照理说,当函数调用结束,里面的局部变量就被释放掉的,所以返回的地址空间里也不是5了,是一个未定义。可是可是问题来了,在主函数的最后一条输出语句中,却输出了5!!!实在不理解。。。

望路过的大神门给指点迷津啊!!!


经过这么一段时间的深入学习,对以上问题有了更深刻的了解与认识。解惑如下:

在函数执行过程中,变量m是一个合法的且正在使用的存储空间,编译器为其他的变量在栈上开辟空间的时候是不能开在这里的,在函数调用结束后变量m会销毁,然而这个销毁是指编译器将这块内存空间置为收回状态,也就是说这块内存空间不属于哪个变量了,而是属于编译器了。但由于没有其他的变量在这里存储,所以这块空间里的值还是原来的,引用的话还是有东西的。如果后来这个引用还存在,且这块内存空间已经被编译器分配给其他的变量了,那么现在引用的就是不符合原意的,并且是非法的,更可能是危险的了(如果新的变量是不允许被改动的)


评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值