因為有一篇文章寫的比較清楚,我自已就沒有多寫,貼在這裡,方便檢視.
看看下面的程式的輸出:
#include
char *returnstr()
int main()
這個沒有任何問題,因為"hello world!"是乙個字串常量,存放在靜態資料區,把該字串常量存放的靜態資料區的首位址賦值給了指標,所以returnstr函式退出時,該該字串常量所在記憶體不會被**,故能夠通過指標順利無誤的訪問。
但是,下面的就有問題:
#include
char *returnstr()
int main()
"hello world!"是乙個字串常量,存放在靜態資料區,沒錯,但是把乙個字串常量賦值給了乙個區域性變數(char 型陣列),該區域性變數存放在棧中,這樣就有兩塊內容一樣的記憶體,這是與前著最本質的區別,當returnstr函式退出時,棧要清空,區域性變數的記憶體 也被清空了,所以這時的函式返回的是乙個已被釋放的記憶體位址,所以列印出來的是亂碼。
如果函式的返回值非要是乙個區域性變數的位址,那麼該區域性變數一定要申明為static型別。如下:
#include
char *returnstr()
int main()
這個問題可以通過下面的乙個例子來更好的說明:
#include
//返回的是區域性變數的位址,該位址位於動態資料區,棧裡
char *s1()
//返回的是字串常量的位址,該位址位於靜態資料區
char *s2()
//返回的是靜態區域性變數的位址,該位址位於靜態資料區
char *s3()
int main()
執行輸出結果:
in s1 p=0xbff92efb
in s1: string's address: 0x80486ac
in s2 q=0x80486ac
in s2: string's address: 0x80486ac
in s3 r=0x804998c
in s3: string
這個結果正好應證了上面解釋,同時,還可是得出乙個結論: 字串常量,之所以稱之為常量,因為它可一看作是乙個沒有命名的字串且為常量,存放在靜態資料區。這裡說的靜態資料區,是相對於堆、棧等動態資料區而言 的。靜態資料區存放的是全域性變數和靜態變數,從這一點上來說,字串常量又可以稱之為乙個無名的靜態變數,因為"hello world!"這個字串在函式 s1和s2 中都引用了,但在記憶體中卻只有乙份拷貝,這與靜態變數性質相當神似。
char *p = "abcdefg";//靜態儲存區
char p = "abcdefg"; // p本身是陣列名了,陣列裡放的字串,是區域性變數,內容是原來的靜態區域內容的拷貝!因此返回p實際上返回的區域性變數位址而不是靜態儲存區位址,和上面不同!
函式返回值 返回區域性變數
函式返回值 返回區域性變數 老徐 看看下面的程式的輸出 include char returnstr int main 這個沒有任何問題,因為 hello world 是乙個字串常量,存放在靜態資料區,把該字串常量存放的靜態資料區的首位址賦值給了指標,所以returnstr函式退出時,該該字串常量所...
區域性變數作為返回值問題
函式返回區域性變數,是返回區域性變數的值。但指標 或位址 是一種特殊的值,所以返回區域性指標變數需要特別注意。正確情況下,作為函式返回值的區域性指標,其所指向物件的作用域應該是 呼叫者作用域 全域性或靜態常量區 指向棧空間物件的指標作為返回值,存在潛在的錯誤。1.返回區域性值變數 cpp view ...
函式返回區域性變數
一般的來說,函式是可以返回區域性變數的。區域性變數的作用域只在函式內部,在函式返回後,區域性變數的記憶體已經釋放了。因此,如果函式返回的是區域性變數的值,不涉及位址,程式不會出錯。但是如果返回的是區域性變數的位址 指標 的話,程式執行後會出錯。因為函式只是把指標複製後返回了,但是指標指向的內容已經被...