涉及到指標、陣列、堆疊、以及printf
阿新 • • 發佈:2019-02-05
轉自: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函式,把棧頂空間內容修改了。雖然儲存了地址,但是原來的內容已經修改了,所以得不到結果。