2016-06-09 31 views
2

下面的代碼片段不能正常工作,在Ubuntu機器上使用GCC進行編譯時,以下程序的輸出爲「S更大」。儘管變量s是-1,並且它明顯小於sizeof(buffer),它是20。但它仍然打印S是Bigger爲什麼下面的代碼打印出「S更大」,即使s更小?

我只能做的邏輯假設是C將變量「s」轉換爲無符號整數並在「If」條件下使用。 如果我的假設是正確的,爲什麼C這麼做,或者如果我錯了,爲什麼這段代碼給這個混淆輸出。

#include <stdio.h> 

int main(void) { 

    int s = -1; 
    char buffer[20]; 

    if(s > sizeof(buffer)){ 
     printf("S is Bigger"); 
    } 
    return 0; 
} 
+0

'sizeof(buffer)'會給你指針的大小,它是32位機器上的4的大小 –

+3

@MaxB'buffer'是一個不是指針的數組。 –

+1

整數推廣。不要比較已簽名和未簽名。或者施展其中一個。你的編譯器應該警告有關簽名和未簽名的比較。 – wildplasser

回答

4

從答案this問題

它的安全提供的int是零或正。如果它是負數,並且size_t的級別等於或高於int,那麼int將被轉換爲size_t,因此其負值將變爲正值。

的sizeof()返回的size_t

+1

當一個新問題與現有(已回答)答案有相同的答案時,請不要將該答案(的一部分)作爲新問題的答案:或者將新問題標記爲dup,或者用現有答案的鏈接發表評論。 – CristiFati

+0

@CristiFati這是好的國際海事組織。這不是一個重複的問題,因爲另一個問題沒有要求比較負值,而「重複」功能表示它是針對重複問題。 –

+1

@ M.M感謝您的評論。但是我不知道操作數的符號是​​否有區別。這是關於提供一個解決方案,其中包含(部分)已經作爲解決方案提供的東西(針對單獨的問題)。例如,對指向外國問題(使用正確答案)的問題的評論是可以的(至少這是我所做的 - 因爲我覺得用現有的答案回答在倫理上不太合理......它將意味着爲別人的工作取得一些功勞)。 – CristiFati

3

你是正確的,編譯器轉換sunsigned int數據類型size_t(這是sizeof操作符的返回值)。所以成爲比較(在我的系統,其中爲size_t是64位):

if (18446744073709551615 > 20) 

這顯然是真實的;)

這是由該標準定義的隱式轉換的一部分。相關部分是標準的6.3.1.8中的「通常的算術轉換」。

另見本post,這等post

戰略的根本規則:

  • 如果兩個操作數具有相同的類型,不需要進一步的轉換。
  • 如果兩個操作數具有相同的整數類型(有符號或無符號),則類型爲較小整數轉換等級的操作數將轉換爲具有較高等級的操作數的類型。
  • 如果具有無符號整數類型的操作數的rank大於或等於另一個操作數的類型的rank,則帶有符號整數類型的操作數將轉換爲具有無符號整數類型的操作數的類型。
  • 如果具有有符號整數類型的操作數的類型可以表示具有無符號整數類型的操作數類型的所有值,則具有無符號整數類型的操作數將轉換爲具有符號整數類型的操作數的類型。
  • 否則,兩個操作數都轉換爲與帶符號整數類型的操作數的類型相對應的無符號整數類型。
相關問題