程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> 函數返回局部變量的幾種情況,局部變量幾種情況

函數返回局部變量的幾種情況,局部變量幾種情況

編輯:C++入門知識

函數返回局部變量的幾種情況,局部變量幾種情況


轉載  http://blog.csdn.net/haiwil/article/details/6691854/

本文主要詳細討論了返回返回局部變量的幾種情況,值得大家注意。

 

一般的來說,函數是可以返回局部變量的。 局部變量的作用域只在函數內部,在函數返回後,局部變量的內存已經釋放了。因此,如果函數返回的是局部變量的值,不涉及地址,程序不會出錯。但是如果返回的是局部變量的地址(指針)的話,程序運行後會出錯。因為函數只是把指針復制後返回了,但是指針指向的內容已經被釋放了,這樣指針指向的內容就是不可預料的內容,調用就會出錯。准確的來說,函數不能通過返回指向棧內存的指針(注意這裡指的是棧,返回指向堆內存的指針是可以的)。

    下面以函數返回局部變量的指針舉幾個典型的例子來說明:

1:

 

[cpp] view plain copy  
  1. #include <stdio.h>   
  2. char *returnStr()   
  3. {   
  4.     char *p="hello world!";   
  5.     return p;   
  6. }   
  7. int main()   
  8. {   
  9.     char *str;   
  10.     str=returnStr();   
  11.     printf("%s\n", str);   
  12.     return 0;   
  13. }  

這個沒有任何問題,因為"hello world!"是一個字符串常量,存放在只讀數據段,把該字符串常量存放的只讀數據段的首地址賦值給了指針,所以returnStr函數退出時,該該字符串常量所在內存不會被回收,故能夠通過指針順利無誤的訪問。

 

 

 

2:

 

[html] view plain copy  
  1. #include <stdio.h>   
  2. char *returnStr()   
  3. {   
  4.     char p[]="hello world!";   
  5.     return p;   
  6. }   
  7. int main()   
  8. {   
  9.     char *str;   
  10.     str=returnStr();   
  11.     printf("%s\n", str);   
  12.     return 0;   
  13. }   

"hello world!"是局部變量存放在棧中。當returnStr函數退出時,棧要清空,局部變量的內存也被清空了,所以這時的函數返回的是一個已被釋放的內存地址,所以有可能打印出來的是亂碼。 

 

 

 

3:

 

[html] view plain copy  
  1. int func()  
  2. {  
  3.       int a;  
  4.       ....  
  5.       return a;    //允許  
  6. }                     
  7.   
  8. int * func()  
  9. {  
  10.       int a;  
  11.       ....  
  12.       return &a;    //無意義,不應該這樣做  
  13. }   

 

局部變量也分局部自動變量和局部靜態變量,由於a返回的是值,因此返回一個局部變量是可以的,無論自動還是靜態,

因為這時候返回的是這個局部變量的值,但不應該返回指向局部自動變量的指針,因為函數調用結束後該局部自動變量

被拋棄,這個指針指向一個不再存在的對象,是無意義的。但可以返回指向局部靜態變量的指針,因為靜態變量的生存

期從定義起到程序結束。

 

4:如果函數的返回值非要是一個局部變量的地址,那麼該局部變量一定要申明為static類型。如下:

[html] view plain copy  
  1. #include <stdio.h>   
  2. char *returnStr()   
  3. {   
  4.     static char p[]="hello world!";   
  5.     return p;   
  6. }   
  7. int main()   
  8. {   
  9.     char *str;   
  10.      str=returnStr();   
  11.     printf("%s\n", str);   
  12.   
  13.     return 0;   
  14. }   

5: 數組是不能作為函數的返回值的,原因是編譯器把數組名認為是局部變量(數組)的地址。返回一個數組一般用返回指向這個數組的指針代替,而且這個指針不能指向一個自動數組,因為函數結束後自動數組被拋棄,但可以返回一個指向靜態局部數組的指針,因為靜態存儲期是從對象定義到程序結束的。如下:

 

 

[html] view plain copy  
  1. int* func( void )  
  2. {  
  3.     static int a[10];  
  4.     ........  
  5.     return a;  
  6. }   

6:返回指向堆內存的指針是可以的

 

[html] view plain copy  
  1. char *GetMemory3(int num)  
  2. {  
  3. char *p = (char *)malloc(sizeof(char) * num);  
  4. return p;  
  5. }  
  6. void Test3(void)  
  7. {  
  8. char *str = NULL;  
  9. str = GetMemory3(100);  
  10. strcpy(str, "hello");  
  11. cout<< str << endl;  
  12. free(str);  
  13. }  

程序在運行的時候用 malloc 申請任意多少的內存,程序員自己負責在何時用 free釋放內存。動態內存的生存期由程序員自己決定,使用非常靈活。

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