2013-07-22 64 views
5

我正在閱讀書籍Cracking the Coding interview(問題1.2)中的問題的解決方案。這裏的目標是在C中實現一個函數void revers(char* str),該函數反轉空終止字符串。在C中,指針的地址可以是0嗎?

該解決方案的代碼看起來是這樣的:

void reverse(char *str) 
{ 
    char* end=str; 
    char tmp; 
    if(str) 
    { 
     while(*end) 
     { 
      end++; 
     } 
     end--; 
     //code to reverse 
    } 
} 

這裏,str包含地址吧?如果str0if(str)只會評估爲false,對吧?

所以我說的是,str將不會包含地址0x0000,因此評估if(str)false

+0

關於類似問題,我可以參考我的答案[這裏](http://stackoverflow.com/questions/17462299/initializing-variable-at-address-zero-in-c/17462496#17462496) ? – Nobilis

+1

除非您自己將'str'作爲零傳遞給函數,否則不會。 –

+0

運行這個:'char * p; printf(「%p」,p);'回答你的問題。 :) – ludesign

回答

2

有沒有這樣的機會,,除非你通過NULL指針函數。

在C中沒有布爾類型,直到它在C99中引入。任何邏輯操作(包括條件)都會檢查一個值爲零,而不管它的實際類型。

+1

你怎麼知道'reverse()'不是用0指針調用的? –

+0

當然,我的意思是如果你傳遞一個有效的指針。我會修復一個答案來澄清。 –

+0

哎呀,似乎我誤解了這個問題。對不起。 –

1

如果你問我應該測試某人在我的函數中傳遞NULL指針,那麼答案是YES。

+0

我不同意。檢查它是否得到有效參數不是函數的責任。如果有人通過傳遞NULL指針進行「錯誤的調用」,那麼讓程序崩潰。當然,這很大程度上取決於上下文,所以它可能不適用於海報的情況。 – Xaqq

+0

@Xaqq這取決於該函數是打算由其他程序員直接調用,還是僅用作內部幫助函數。如有疑問,請謹慎處理。 – DuncanACoulter

4
if(str) 

相當於與

if(str != NULL) 

if(str != 0) 

該測試不測試str是否具有0一個地址,它測試str是否是空指針。

請注意,空指針不必具有地址0,標準只確保空指針不等於任何其他非空指針。

C11 6.3.2.3 指針

一個整數常量表達式用值0,或者這樣轉換爲類型 無效*的表達式,被稱爲一個空指針constant.66)如果一個空指針常量被轉換爲指針類型,所產生的指針稱爲空指針,保證與指向任何對象或函數的指針進行比較。

1

是可能的,如果str是在其上已經預留地址0x000null pointer任何架構NULL指針。

1

if(str)被添加來檢查str是否分配了內存。最佳做法是在聲明它時初始化一個指向NULL的指針。

上述等於

if(str != NULL) 
{ 

} 
2

所以,我要說的是,有沒有機會,STR將包含地址爲0x0000,從而評估是否(STR)爲假?

是的,有:如果您用空指針調用reverse(),它將評估爲false。

這被用作安全網,以防reverse()被調用時帶有空指針,以便代碼在實際反轉字符串時不訪問無效內存。

3

理論上0x0指針是有效的,但所有時下編譯器不會給你虛擬地址0,因爲它被保留來表示空指針(指向沒有)。

某些內核可能仍在使用它,但除非您在非常罕見的內核中編寫非常低級別的內容,否則可能會認爲0x0未指向任何內存。

對於指針沒有指向任何內容的值,創建了NULL常量。現在NULL一直值爲0

13

str確實包含地址(這是一個指針char)和if(str)將評估爲false 當且僅當str等於空指針

請注意,空指針不是標準所要求的地址0;然而,標準要求當在指針上下文中使用時,的文字值0必須由編譯器解釋爲空指針的地址 - 無論這可能是什麼。

這意味着測試if(p == 0)保證始終與if(p == NULL)相同。此外,條件if(p)保證始終與if(p != 0)相同。

結論:您的代碼將始終檢測到空指針,與指向地址爲零的指針不同(即使在實踐中您會發現它通常是)。

1

在這裏,str包含一個地址的權利?

是的。這是一個char *。其值代表char的地址。

如果(str)只在str爲0時計算爲false,對嗎?

是的。

是否有機會str將包含地址0x0000,因此 評估如果(str)爲false?

這是完全可能的。只需使用該值調用該函數即可。

char * myCharPointer = 0; 
reverse(myCharPointer); 

不過我從來不使用這種風格。我更喜歡使用NULL,這是由C標準保證的等價。我更喜歡NULL,因爲它更具表現力,它有助於將普通整數值與地址分開。

char * myCharPointer = NULL; 
reverse(myCharPointer); 

參見以下相關問題:

0

聲明

if (str) 

相當於

if (str != 0) 

這又是由編譯器解釋爲

if (str != null-pointer-value-for-char-pointer-type) 

即它根本與「地址零」無關。編譯器需要識別指針上下文,並與char *類型的與實現相關的空指針值進行比較。後者將由實現相關的地址值(不一定是零地址)在物理上表示。