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。

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 就沒問題了。
最后,請采納?@朕日理萬機 的回答。


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 也沒關系了。
添加回答
舉報