涉及到指针、数组、堆栈、以及printf

转自:http://zhidao.baidu.com/question/326625441.html
首先,这个问题有点2,下面我开始了。
一个2一点的程序:
#include <stdio.h>
char *f()
{
	char arr[]="hello";
	return arr;
}
void main()
{
	char *p;
	p=f();
	printf("%s\n",p);
}
我们知道,这个程序打印出来的是乱码,因为那个函数f中的arr数组的空间是分配在栈中的,当函数调用结束时,系统自动回收内存。
但是,这个但是很重要,我们知道,所谓的回收就是把栈顶指针改变,但是栈中的内容不会变,所以如果把打印语句改成
printf("%c\n",*p);
我们就会打印出一个'h',同样,在打印语句中加上
p++;
这条语句,就会打印出'e',如果是p+=2,就会打印出'l'。。。以此类推。

高潮来了:
如果我的main函数是这样的:
void main()
{
	char *p;
	p=f();
	printf("%c\n",*p);
	p++;
	printf("%c\n",*p);
	p++;
	printf("%c\n",*p);
	p++;
	printf("%c\n",*p);
	p++;
	printf("%c\n",*p);
}
我是想打印hello出来的,可是只有一个h打出来了,后面的是乱码。
我把第一个printf语句删掉后,就会把e打印出来,后面还是乱码。
如果我一次性删两个printf,就会把l打印出来,后面是乱码。
。。。。。。
请问第一个printf语句肿么了,以至于排在后面的printf语句都打印出了乱码,伤不起啊~~~~~。希望高手解救我
解答:
 
 
printf函数,正如第一个人所说,调用函数printf前先要将形参压栈,这时候要计算*p
所以,第一条printf语句已经把参数算出来并放到栈顶保存了。然后调用printf函数(函数调用需要用到栈建立访问连和控制链,而,原来的函数f执行完了,原本f是在栈顶的,所以,函数f的栈空间释放。数组空间也被释放),printf占用了栈,所以,把原来函数f的栈空间内容修改了。所以,第一条printf语句是可以得到结果的。后面因为arr空间的内容已经被修改,所以,之后的printf语句都得不到结果。

顺便再解释一下printf("%s\n",p);得到的为什么是乱码。
正如上面所说,先计算参数p的值保存栈顶。保存的值为arr的地址。然后调用printf函数,把栈顶空间内容修改了。虽然保存了地址,但是原来的内容已经修改了,所以得不到结果。 

猜你喜欢

转载自blog.csdn.net/u012033076/article/details/50423684