转自: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函数,把栈顶空间内容修改了。虽然保存了地址,但是原来的内容已经修改了,所以得不到结果。