返回區域性變數沒問題
如果返回區域性變數有問題,函式的意義還有嗎?
全域性變數還用返回嗎?
返回指向區域性變數的指標才有問題
, 函式退棧之後,區域性變數消失, 指標將指向未知區域,所以出現問題。
返回區域性變數的引用也是絕對不可以的
。 引用只是變數的乙個別名,變數本體都不存在了,引用當然也沒有任何意義。
還有,如果是堆空間,可以返回,即在函式中用new
申請的空間,是可以返回的
。但是一般的情況下,好的風格是:
盡量在同乙個作用域內成對使用new
和delete
,(也即不要返回堆空間),因為如果不是這樣,會是你的函式的介面變的不夠靈活, 試想每個呼叫你的函式的人還需要記得去delete
掉你在函式中
new的堆空間, 否則就會造成記憶體洩露。
返回啥其實都是值拷貝! 指標就是指標值拷貝,
不會拷貝被指向的內容。
永遠不要從函式中返回區域性自動變數的位址
。如果你真的需要這樣操作。
你可以在函式的參數列中傳入乙個指標變數
。然後將需要寫入的資料寫入到該指標變數指向的位址。由於該指標指向的變數,作用域在函式體 之外。因此不會在函式結束結束時被**。
在c語言中為什麼說絕不能返回函式內區域性變數的位址?
在程式中,只在特定的過程或函式中可以訪問的變數,是相對與全域性變數而言的。
全域性變數也稱為外部變數,是在函式的外部定義的,它的作用域為從變數定義處開始,到本程式檔案的末尾。全域性變數全部存放在靜態儲存區,在程式開始執行時給全域性變數分配儲存區,程式行完畢就釋放。
區域性變數可以和全域性變數重名,但是區域性變數會遮蔽全域性變數。在函式內引用這個變數時,會用到同名的區域性變數,而不會用到全域性變數。
區域性變數的特點是:隨函式呼叫時建立 隨函式結束時析構(銷毀)。
設想,如果返回了乙個區域性變數的指標,而恰好區域性變數偏偏又在函式結束後銷毀,但指標並沒有被銷毀,而是被返回,那也就是說,指標指向的正是乙個被銷毀了的物件。
一般的來說,函式是可以返回區域性變數的。
區域性變數的作用域只在函式內部,在函式返回後,區域性變數的記憶體已經釋放了。因此,如果函式返回的是區域性變數的值,不涉及位址,程式不會出錯。但是如果返回的是區域性變數的位址(指標
)的話,程式執行後會出錯。因為函式只是把指標複製後返回了,但是指標指向的內容已經被釋放了,這樣指標指向的內容就是不可預料的內容,呼叫就會出錯。準確的來說,函式不能通過返回指向棧記憶體的指標
(注意這裡指的是棧,返回指向堆記憶體的指標是可以的)。
下面以函式返回區域性變數的指標舉幾個典型的例子來說明:
1: view plain
copy to clipboard
1. #include
2. char *returnstr()
3.
7. int main()
8.
這個沒有任何問題,因為"hello world!"
是乙個字串常量,存放在唯讀資料段,把該字串常量存放的唯讀資料段的首位址賦值給了指標,所以
returnstr
函式退出時,該該字串常量所在記憶體不會被**,故能夠通過指標順利無誤的訪問。
2: view plain
copy to clipboard
1. #include
2. char *returnstr()
3.
7. int main()
8.
"hello world!"是區域性變數存放在棧中。當returnstr函式退出時,棧要清空,區域性變數的記憶體也被清空了,所以這時的函式返回的是乙個已被釋放的記憶體位址,所以有可能列印出來的是亂碼。
3:view plain
copy to clipboard
1. int func()
2.
7.
8. int * func()
9.
區域性變數也分區域性自動變數和區域性靜態變數,由於a返回的是值,因此返回乙個區域性變數是可以的,無論自動還是靜態,
因為這時候返回的是這個區域性變數的值,但不應該返回指向區域性自動變數的指標,因為函式呼叫結束後該區域性自動變數
被拋棄,這個指標指向乙個不再存在的物件,是無意義的。但可以返回指向區域性靜態變數的指標,因為靜態變數的生存
期從定義起到程式結束。
view plain
copy to clipboard
1. #include
2. char *returnstr()
3.
7. int main()
8.
5: 陣列是不能作為函式的返回值的,原因是編譯器把陣列名認為是區域性變數(陣列)的位址。返回乙個陣列一般用返回指向這個陣列的指標代替,而且這個指標不能指向乙個自動陣列,因為函式結束後自動陣列被拋棄,但可以返回乙個指向靜態區域性陣列的指標,因為靜態儲存期是從物件定義到程式結束的。如下:
view plain
copy to clipboard
1. int* func( void )
2.
6:返回指向堆記憶體的指標是可以的
view plain
copy to clipboard
1. char *getmemory3(int num)
2.
6. void test3(void)
7.
程式在執行的時候用 malloc
申請任意多少的記憶體
,程式設計師自己負責在何時用
free
釋放記憶體。動態記憶體的生存期由程式設計師自己決定
,使用非常靈活。
函式返回區域性變數的指標或引用
一般來說,由於在離開函式後區域性變數會被釋放,所以是不允許函式返回指向區域性變數的指標或引用的。我們往往需要遵循如下原則 引用作為返回值,必須遵守以下規則 1 不能返回區域性變數的引用。主要原因是區域性變數會在函式返回後被銷毀,因此被返回的引用就成為了 無所指 的引用,程式會進入未知狀態。2 不能返...
不能返回區域性變數的引用
源之 int add1 int a,int b int add2 int a,int b 請問這兩個函式返回有什麼區別,是乙個返回副本,另乙個直接返回嗎?呼叫函式add2有什麼危險嗎?add1的確返回了乙個副本,如果sum是自定義的類型別,可以很明顯看出拷貝建構函式在返回時被呼叫,對於內建型別沒什麼...
千萬不能返回區域性變數的引用??
c primer第7章函式一節,講到返回時,理解返回引用至關重要的是,千萬不能返回區域性變數的引用 意思是返回程式內部定義的變數時可能會出問題,因為當函式執行完畢後,將釋放分配給區域性物件的儲存空間。此時,對區域性物件的引用就會指向不確定的記憶體。覺得不能理解。比如求階乘時,可以使用迭代函式的方法,...