程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> C語言:一個涉及指針函數返回值與printf亂碼、內存堆棧的經典案例

C語言:一個涉及指針函數返回值與printf亂碼、內存堆棧的經典案例

編輯:關於C語言

C語言:一個涉及指針函數返回值與printf亂碼、內存堆棧的經典案例


一個奇怪的C語言問題,涉及到指針、數組、堆棧、以及printf。下面實現:

整數向字符串的轉換,返回字符串指針,並在main函數中調用printf顯示。
  1. #include
  2. #include
  3. #include
  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
  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函數,把棧頂空間內容修改了。雖然保存了地址,但是原來的內容已經修改了,所以得不到結果。
來源:

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved