亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

指針初始化的問題

指針初始化的問題

慕粉1600176492 2016-12-12 21:29:23
例子(1) #include"stdio.h" ?int?main() ?{ ???int?a,c,*t;? ???int?*p=&a,*q=&c; ????*t=*p; ????*p=*q; ????*q=*t; ???return?0; ?} ?例子(2) ?#include"stdio.h" ??int?main() ??{ ?????int?a,c,*t=0; ?????int?*p=&a,*q=&c; ?????*t=*p; ?????*p=*q; ?????*q=*t; ?????return?0; ??} ??//請問這兩個例子有什么區別嗎?為什么有的書上寫著第一種情況如果p指向了某一個重要的數據,那么就會被改變, ??//我初始化的概念不太清楚,是不是定義的時候才算初始化,第一種情況是不是比較危險,那第二種方法會不會更好點呢?
查看完整描述

3 回答

已采納
?
朕日理萬機

TA貢獻27條經驗 獲得超28個贊

兩個實現其實都非常危險。不知道這個例子是不是你為了簡化代碼自己刪減了,還是教科書上原本就這么寫的。

先說第二個。int *t = 0,在現代編譯器里,意思是把空指針賦值給t,空指針是不允許解引用的,你如果運行一下你第二個代碼,應該會得到一個segmentation fault。(感謝@onemoo 網友指出,C語言標準中把0賦值給指針,相當于把NULL賦值給指針。C++11引入了nullptr關鍵字,從此建議用它作為空指針)??傊罩羔樜ㄒ坏淖饔檬怯脕肀容^,其他操作都應該避免。你可以把指針初始化為空,然后在運行時把某個地址賦給它,然后要操作時先判斷是否為空。

然后說第一個變量默認初始化,如果是靜態或者全局變量,比如不屬于任何函數體中的變量,int會初始化為0,指針會初始化為空指針。而你的代碼,不管a, c, *t都是函數中聲明的局部變量(存在于棧上),會用某些不確定的值去初始化它們。a和c還好一點,它們會有不確定的值,你如果后面不依賴于a和c做什么重要的事情就沒關系。而t會指向某個不確定的地址,它可能關系到別的代碼,你在中間改變t指向的地址的值,就是很危險的事情,可能會影響別的調用。所以真正危險的不是p,而是t。


查看完整回答
2 反對 回復 2016-12-14
  • onemoo
    onemoo
    實際上,C標準規定,整型常量0就是NULL指針,所以這不是“未定義”或“未指定”行為
  • 朕日理萬機
    朕日理萬機
    C語言里的確是有宏定義#define NULL 0。不過從c++11開始不建議用NULL 和 0作為空指針了,而改用nullptr關鍵字。原因我也不太清楚,有說法是可能引起函數重載的混亂。不過的確如你所說,大部分情況下0就是作為空指針使用
  • onemoo
    onemoo
    是的,C++11不再使用0,而增加了nullptr作為null pointer常量值。 但C標準(至少在C99及C11標準中都是如此)規定整型常量0是null pointer常量值,且在<stddef.h>定義為NULL宏。所以使用0作為null pointer在C中仍是安全且確定的。
?
onemoo

TA貢獻883條經驗 獲得超454個贊

抱歉,題主,我之前的回答有誤,謝謝 @朕日理萬機 指出錯誤。你可以看帖子中我們倆的討論。


具體來說,我回答中的“但是你在真正使用 t 之前就向 t 賦予了適當的值(通過 p 使其指向 a)”說錯了

*t=*p ?并不是讓 t 指向 a,這語句只是在 t 所指的內存中存入 p 所指的值(也就是 a 的值)。

那么在第一例中,這時 t 還沒有適當的值,所以可能會引起嚴重的問題。

而在第二例中,t 是個NULl指針,解引用NULL指針會直接引起segmentation fault。


要使用指針,一定要確保其指向適當的、有意義且安全的地址。

對于你這里的代碼,如果一定要通過指針來交換a、b值,那么也要先讓 t 指向一個安全可使用的內存,比如:

  • 你可以再定義一個int c,然后讓 t 指向 c

  • 也可以用 malloc(sizeof(int)) 申請一塊內存,讓 t 指向這里

這樣就可以確定 t 指向的是安全可用的內存,然后再利用 *t 來交換 *p *q 就沒問題了。


最后,請采納?@朕日理萬機 的回答。

查看完整回答
1 反對 回復 2016-12-14
?
onemoo

TA貢獻883條經驗 獲得超454個贊

就這兩個簡單的代碼來說,沒有區別!

例子1中,你先定義了int指針 p,隨后 p = &a; 把變量 a 的地址賦值給 p,也就是 p 會指向 a。 像這樣在定義時沒有指定初值的話,p 的值是不確定的!也就是 p 指向什么是不確定的。你這時不應該使用 p 的值,當然你后面為 p 賦了確定的值后就沒有關系了。

例子2中,你在定義指針 p 的同時提供了初值,所以定義好的 p 的初值就是指向 a 的。

所以從結果來看這兩個例子并沒有什么區別。


“第一種情況如果p指向了某一個重要的數據,那么就會被改變”

——這個代碼中顯然 p 開始時并沒有指向重要數據。另外,假如 p 之前指向了什么,那么“就會被改變”,這指的是什么被改變?? ?

p 被改變嗎? 那當然了,p=&a 這就是為 p 賦值啊,當然會改變 p 的指向了。 但這并不會改變被 p 所指的對象的值! ?所以也沒什么關系。 而且你既然已經要為 p 賦值了,就說明你已經打算讓 p 指向新的東西了,原來所指的東西重不重要跟 p 也沒關系了。

查看完整回答
反對 回復 2016-12-12
  • 慕粉1600176492
    慕粉1600176492
    不好意思,上次那個問題不正確,我重新舉了兩個例子,幫忙看一下。
  • onemoo
    onemoo
    那我再回一貼吧。不過,這兩個新的例子和老的沒區別呀...
  • 3 回答
  • 0 關注
  • 2011 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號