前面看了幾篇關於函數傳回值的文章,覺得學多了進階程式語言,還是有必要對一些底層的只是需要瞭解一些
下面我總結了一些,肯定是不全,還望大家給予指正O(∩_∩)O~
當我們使用一個被調函數的時候,return的時候分為兩個情況,一個是返回數值,一個就是指標(或者引用)
當我們返回數值的時候,編譯通過,沒有問題,輸出結果也沒有問題,如下代碼是通過測試的
#include <stdio.h>int sum(int a,int b){ int s; s=a+b; return s;}int main(void){ int a,b; scanf("%d%d",&a,&b); printf("%d\n",sum(a,b)); return 0;}
解析:主調函數(也就是main函數)調用sum函數的時候,sum函數的局部變數s就是兩個實參的副本的和,是存放在棧裡面的,此時會進行一個壓棧的操作
當調用函數結束的時候,也就是return了,此時局部變數就會隨著函數的結束被銷毀,但是銷毀的是s,數值會通過副本傳回主函數,也就是進行了一個出棧的操作
其實實質也就是傳回了該值的一個副本,也就是兩個數的和,這是一個實實在在的數字
所以運行結果是ok的
但是如果當我們想要返回一個指標的時候,就會出現問題的
比如以下的代碼
#include <stdio.h>char*GetMemory(void){ char p[]="hello world"; return p;}int main(void){ char *str=NULL; str=GetMemory(); printf(str); return 0;}
解析:之前在別的地方看到一個很形象的解釋,就是你去旅遊,覺得當地的一家酒店的飯菜很有特色,於是就記下了它的地址門牌號之類的(相當於指標),當你回去之後,也就是函數調用完畢,返回這個指標是沒有問題的,你回去之後是依然可以看這個地址門牌號的,但是當一段時間再去上次旅遊的地方,可能那家酒店已經不存在了,可能變成了一家理髮店或者其他什麼的
所以,當函數調用結束,指標所指向的內容是存放在棧的,會隨著函數一起銷毀的,但是指標還是存在的,只不過此時指標指向的內容不確定,所以結果是會出錯的(跟上面傳值回來是一回事,傳遞一個指標的副本回主調函數,但是該指標是指向被調函數的局部變數,該局部變數是已經隨著被調函數已經銷毀掉的,所以這時指指標的指向是不確定的,至少是未知的,所以容易出現錯誤)
但是通過其他方法我們可以避免對指標返回的錯誤
比如延長指標的生命期,將其設定為靜態變數,使其生命期延長至整個檔案
或者設定成一個字串的常量,讓其存放在靜態區中也是可以的
實現的代碼如下
#include <stdio.h>char *GetMemory(void){static char p[]="hello world";return p;}int main(void){printf("%s\n",GetMemory());return 0;}
#include <stdio.h>char *GetMemory(void){ char *p="hello world";return p;}int main(void){printf("%s\n",GetMemory());return 0;}
還有總結的不足之處歡迎大家批評指正,以此共同學習,共同進步