簡體   English   中英

C中的unsigned int表現為負

[英]Unsigned int in C behaves negative

我不明白為什么對於以下代碼,無符號int的輸出為負。 就像一個簽名的int一樣。

  uint32_t yyy=1<<31;
  printf("%d\n",yyy);

輸出為:

-2147483648

這是-2^31

%d的格式說明符期望一個int ,而不是一個unsigned int ,因此代碼具有未定義的行為。 根據C99標准第7.19.6.1,fprintf函數

如果任何參數都不是相應轉換規范的正確類型,則行為未定義。

%u用作unsigned int

uint32_t yyy=1u<<31;
printf("%u\n",yyy);

輸出:

2147483648

這是因為您的printf參數(如%d)正在將您的數字隱式轉換為int。

請改用%u。

使用%u輸出無符號數字:

printf("%u\n", yyy);

正如許多人所說,使用%u標識符。

這樣做的原因是, printf無法判斷任何額外參數的類型(它們以va_list形式給出),因此程序員必須使用格式字符串提供該信息。 當您隨后提供%dprintf將調用此命令:

int val;
val = va_arg(va_list, int);

並將您的unsigned int隱式轉換為有符號。

您需要使用unsigned int格式說明符:

printf("%u\n",yyy);
        ^^

對於printf使用錯誤的格式說明符是未定義的行為,這在C99草案標准第7.19.6.1節中進行了介紹7.19.6.1 函數 ,其中還涉及關於格式說明符的printf ,它說:

如果轉換規范無效,則行為未定義。 248)如果任何參數都不是對應轉換規范的正確類型,則行為未定義。

printfcppreference頁面有一個漂亮的表,用於指定可用的格式說明符。

因為您將其打印為已簽名。 請改用%u

printf采用可變數量的參數。 當您調用它時,編譯器會盡職地將它們全部放入堆棧中。 因為它是C,所以沒有反射printf隨后無法推斷收到的東西的類型。 在位級別上,您不能從表面上區分無符號整數或浮點數,合適的較小結構,較大結構的一部分等形式的有符號整數。

這就是為什么您還必須提供格式字符串的原因。 它告訴printf從堆棧讀取什么類型以及以什么順序讀取。 它完全取決於該格式字符串,無法對其進行驗證。

因此,按照已經發布的單行答案,如果您告訴它將字段解釋為簽名數量,則它將被打印為簽名數量。

整數以二進制補碼格式存儲。 這意味着僅通過查看值就無法判斷該數字是帶符號的還是無符號的。 您必須告訴機器要使用哪種表示形式,並自己對其進行跟蹤。

在您的示例中,您告訴機器jjj是無符號的(用於類型檢查),然后通過在格式字符串中使用%d來要求printf()將其視為已簽名(無法獲得類型信息)。 如果要打印無符號整數,請使用%u

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM