首页 > 代码库 > C语言:一个涉及指针函数返回值与printf乱码、内存堆栈的经典案例

C语言:一个涉及指针函数返回值与printf乱码、内存堆栈的经典案例

一个奇怪的C语言问题,涉及到指针、数组、堆栈、以及printf。下面实现:

整数向字符串的转换,返回字符串指针,并在main函数中调用printf显示。
  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. #include<string.h>
  4. char* swich(int n)
  5. {
  6. char A[20],B[20];
  7. char*p;//=(char*)malloc(4*sizeof(char));
  8. int i=0,a;
  9. int minus=0;
  10. if(n<0)
  11. {
  12. minus=1;
  13. n=-n;
  14. }
  15. while(n/10!=0)
  16. {
  17. a=n%10;
  18. n=n/10;
  19. A[i++]=‘0‘+a;
  20. }
  21. a=n%10;
  22. A[i++]=‘0‘+a;
  23. if(minus==1)
  24. A[i++]=‘-‘;
  25. A[i]=0;
  26. int len=i;
  27. int j=len-1;
  28. i=0;
  29. while(i<len)
  30. {
  31. B[i]=A[len-1-i];
  32. i++;
  33. }
  34. B[i]=0;
  35. p=B;
  36. printf("%s,",p);
  37. return p;
  38. }
  39. void main()
  40. {
  41. int a=-234;
  42. char* p=swich(a);
  43. char b[10];
  44. strcpy(b,p);
  45. int i=0;
  46. printf("%s,",b);
  47. }
上面程序执行结果如下:
在swich函数中,234能正常输出。
而在main中输出的却是乱码,如果在main中用
  1. for(int i=0;i<3;i++)
  2. {
  3. printf("%c",p[i]);
  4. }
则只有‘2‘能正确输出,p[1],p[2]乱码。

这是什么原因呢?
调用函数printf前先要将形参压栈,这时候要计算*p。所以,第一条printf语句已经把参数算出来并放到栈顶保存了。然后调用printf函数(函数调用需要用到栈建立访问连和控制链,而原来的函数f执行完了,原本f是在栈顶的,所以,函数f的栈空间释放。数组空间也被释放),printf占用了栈,所以,把原来函数f的栈空间内容修改了。所以,第一条printf语句是可以得到结果的。后面因为arr空间的内容已经被修改,所以,之后的printf语句都得不到结果。
顺便再解释一下printf("%s\n",p);得到的为什么是乱码。
正如上面所说,先计算参数p的值保存栈顶。保存的值为arr的地址。然后调用printf函数,把栈顶空间内容修改了。虽然保存了地址,但是原来的内容已经修改了,所以得不到结果。

来源: <http://zhidao.baidu.com/question/326625441.html>
 

C语言:一个涉及指针函数返回值与printf乱码、内存堆栈的经典案例