1. 程式人生 > >C指標以及為什麼不能返回區域性指標變數,卻可以返回區域性變數

C指標以及為什麼不能返回區域性指標變數,卻可以返回區域性變數

指標,是一個無符號整數(unsigned int),它是一個以當前系統定址範圍為取值範圍的整數。

如:int* 是一個指標變數型別
指標變數和普通變數沒有什麼區別,指標32位四位元組,裡面儲存的是一個記憶體空間的地址,
就像一個整形變數int a, a就可以代表一個整數,一個指標變數int* p,p就可以代表一個
地址資料,而*地址,代表去這個地址指向的記憶體空間取出裡面的內容,因此如果是要取出
這個指標所指向的記憶體裡面的內容就是*p,而如果是需要獲得那個記憶體的地址,或者讓另外
一個指標指向這個空間時,就可以使用int* pb;pb=p;


&變數名這是獲取儲存這個變數的記憶體空間地址
應該說c語言是門十分靈活的語言,型別幾乎可以說無所謂了,有的只有記憶體和讀取的方式
,什麼幾級指標,都沒有意義,就算是一整形,只要強轉,也可以當作地址資料來用,只是
可能會段錯誤,因為沒有做地址對映


*p代表的是地址裡面的儲存的值
p代表的是一個指標變數


int* p[10]  *和[]優先順序相同,平級右結合  p為一個數組,包含了10個指標變數
int (* p)[10]  p為指向一個數組的指標


為什麼不能返回區域性指標變數,卻可以返回區域性變數
函式的區域性變數用作返回值時,會生成一個區域性變數的拷貝用作返回值,之後區域性變數會被系統回收,函式不能返回區域性變數的地址,因為如果返回區域性變數的地址,系統回收後,指標指向的內容就無意義了,但是對於靜態變數也可以返回其指標。
#include "stdio.h"


int *a()
{
    int b;
    int *p;
    b=23;
     printf("b=%d \n",b);
    return &b;


}
void main()
{


   int *r;
   r=a();
//printf("");
   printf("r=%d",*r);
   getch();
}


如以上程式碼,函式返回的是區域性變數的指標,此時在主函式裡打印出的r應該不等於23,可是實際結果卻是23,當在列印結果之前再添
加一個printf語句時列印的結果才不會是23,在CSDN上討論:http://topic.csdn.net/u/20120206/22/487c9e4f-bf36-4ed1-9e6a-a6e7
cb7404e5.html?seed=1431559918&r=77464424#r_77464424,這裡系統可能沒及時回收區域性變數才導致打印出的還是區域性變數的值
具體的應該如下:
1. 如果返回一個基本型別的變數,比如: 
int a; 
a = 5; 
return a; 
那麼就會a的一個拷貝,即5返回,然後a就被銷燬了。儘管a被銷燬了,但它的副本5還是成功地返回了,所以這樣做沒有問題。 


2. 但是對於指標,像1那麼做就會有問題,比如在某個函式內部: 
int a[] = {1, 2}; 
return a; 
那麼也會返回指標a的一個拷貝,我們假定a的地址值為0x002345FC,那麼這個0x2345FC是能夠成功返回的。當return執行完成後,a就
要被銷燬,也就是0x002345FC所指向的記憶體被回收了。如果這時候在函式外面,去地址0x002345FC取值,那得到的結果肯定是不對的
。這就是為什麼不能返回區域性指標的原因。返回區域性變數的引用的道理和這個類似。 


3. 對於靜態變數: 
static int b=10; 
return &b; 
由於靜態變數是存放在靜態儲存區的,所以不會被系統回收,所以返回值還是有效的。

相關推薦

C指標以及為什麼不能返回區域性指標變數可以返回區域性變數

指標,是一個無符號整數(unsigned int),它是一個以當前系統定址範圍為取值範圍的整數。 如:int* 是一個指標變數型別 指標變數和普通變數沒有什麼區別,指標32位四位元組,裡面儲存的是一個記憶體空間的地址, 就像一個整形變數int a, a就可以代表一個整數,一

C++ 虛擬函式表指標以及虛擬函式指標的確定

【摘要】 很多教材上都有介紹到虛指標、虛擬函式與虛擬函式表,有的說類物件共享一個虛擬函式表,有的說,一個類物件擁有一個虛擬函式表;還有的說,無論使用者聲明瞭多少個類物件,但是,這個VTABLE虛擬函式表只有一個;也有的在說,每個具有虛擬函式的類的物件裡面都有一

函式指標以及成員函式指標_成員變數指標

這篇是為了加深記憶所寫。發現,很多知識若不經過反覆的琢磨和動手實踐,是很難記得住的。 1)  函式指針的初始化。 函式如下: 1 int CompareString(const string& str1, const string& str2)2 {3     return str1.co

c語言中的變數(區域性變數外部變數靜態變數暫存器變數) .

c語言中變數分為四類,分別是 1.auto   自動變數 2.static   靜態存貯分配變數(又分為內部靜態和外部靜態) 3.extern  外部變數/全程變數(用於外部變數說明) 4.register  暫存器變數(分配在硬體暫存器中) 四

C#如何通過顯示一次子窗體判斷返回的DialogResult的具體值

有時候我們需要來顯示一次窗體,然後判斷返回的DialogResult的值。我餓麼可以直接這樣寫 FrmNewWinform  new_frm = new FrmNewWinform(); new_frm.ShowDialog(); if(new_frm.DialogR

fatal error LNK1169: 找到一個或多個多重定義的符號或多個.c/.cpp檔案想同時呼叫定義在.h檔案裡面的全域性變數防止重定義變數問題。

為什麼.h檔案中不能定義全域性變數? 原因: 存在多次建立變數.如果標頭檔案中可以定義全域性變數,那麼每個包含該標頭檔案的檔案裡都會有該全域性變數的定義.因為C語言的include是直接將檔案嵌入到include這個地方的. 解決辦法: ​在標頭檔案使用 extern 來宣告該全域性變

js的變數作用域區域性變數全域性變數全域性和區域性變數重名

一、變數的作用域:  變數起作用的範圍,變數在啥地方能用。那麼啥地方就是它的作用域。二、變數作用域分為:區域性變數和全域性變數。1、區域性變數://就是定義在函式內部的變數(內部變數),區域性變數起作用的範圍是函式內部。//區域性變數就是私有的變數2、全域性變數://就是定義

字符串數組 輸入3個字符串要求按由小到大的字母順序輸出; 輸入n個學生的姓名和學號到字符串數組中在輸入一個姓名如果班級有該生則返回其信息否則返回本班無此人

emp zhang 查詢 i+1 [1] 返回 思路 lan 字符數組 輸入3個字符串,要求按由小到大的字母順序輸出 如 輸入franch england china,輸出結果是china england franch 三個數排序輸出,比較三個數的大小怎麽做? a=18 b

學習SpringBoot遇到的問題(1)路由返回靜態頁面返回了靜態檔案的路徑

一、路由返回靜態頁面,卻返回了靜態檔案的路徑 解決: 1、註解使用錯誤 controller類的註解應該是 @Controller 而不是@RestController 前者只要返回RseonBody,後者可返回頁面 2、上述設定成功,卻報錯,形如: Whitelabe

SpringBoot返回date日期格式化解決返回為TIMESTAMP時間戳格式或8小時時間差(轉載)

@JSONField(format = "yyyy-MM-dd HH:mm:ss")  //FastJson包使用註解     @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8") //Jack

《為什麼非靜態內部類中不能有static屬性的變數可以有static final屬性的變數?》

每當我們翻閱有關Java的入門書籍,進入關於內部類的章節時,我們經常可以看到某某書上寫道: ——非靜態實名內部類(成員內部類)中不能含有static修飾的變數,但是可以含有st

java跨方法傳遞物件引用變數並對該變數賦值引起的問題

關於物件引用做方法引數問題,在java中 基本型別變數做引數傳另外一個方法中重新賦值時,會重新在棧中複製一份,物件引用也是一樣,如 public methodA(){ int i = 0; method

JAVA不使用第三個變數交換兩個變數的值

我們先看看使用第三個變數的方法。 public class Swap{ public static void main(String[] args){ int a = 3;

ajax區域性重新整理後如何讓區域性中的百度分享重新載入

我這個人不怎麼喜歡說太多話,看幾個圖你們就懂了 Ajax前 Ajax之後 原因分析 解決方法 收工 百度分享是集成了眾多主流第三方網站分享和收藏按鈕的工具。 通過百度分享輕鬆將主流第三方網站的分享按鈕全部整合到自己網站上,滿足網站使用者的分享需求,並通過在第三方網站的分享內容和

為什麼memcpy要返回一個void*啊沒有返回值不可以嗎

返回void*僅僅是為了方便, 可以直接放在其他的函式裡連續呼叫 例如: #define SIZE(x) (sizeof(x)/sizeof(*x))char BufDet[20];char BufSrc1[] ="i like";char BufSrc2[] ="you"

SpringMvc中Controller方法的多種實現方式(指定返回到哪個頁面指定返回到頁面的資料)

1)ModelAndView@RequestMapping("/list") public ModelAndView itemsList() throws Exception{ List<Items> list = itmesService.lis

Windows10中配置Java環境變數解決配置環境變數依然出現javac提示不是內部或外部命令的問題

安裝好JDK後,我們發現使用java命令沒有問題,但是javac卻會提示不是內部或外部命令。安裝我們一般的配置是這樣的:單擊“計算機-屬性-高階系統設定”,單擊“環境變數”。在“系統變數”欄下單擊“新建”,建立新的系統環境變數。(1)新建->變數名"JAVA_HOME"

SpringBoot返回date日期格式化解決返回為TIMESTAMP時間戳格式或8小時時間差

問題描述        在Spring Boot專案中,使用@RestController註解,返回的java物件中若含有date型別的屬性,則預設輸出為TIMESTAMP時間戳格式 ,如下所示: 解決方案        解決方案有多種,這裡只記錄本人覺得最簡單的一種。一

C語言 子函式返回一個區域性指標變數的疑惑

輸出結果如下圖: 我的分析: 記憶體分佈圖如下圖: 當子函式返回後,區域性變數已經超出了作用域啊,為什麼在main()函式中還能通過指標rp間接訪問變數x呢??為什麼第一次訪問可以輸出12,第二次訪問就記憶體釋放了呢,輸出一個隨機數????