簡體   English   中英

如何確認C中unsigned char的范圍?

[英]How can I confirm the range of unsigned char in C?

我的編譯器的unsigned char包含1個字節。

所以據我所知,unsigned char的范圍是0到2 ^ 8 - 1,即255。

現在我想確認無符號字符的最大整數可以顯示為255。

以下是我的代碼:

#include <stdio.h>
#include <limits.h>
int main(void)
{
    printf("unsigned char has %d bytes.\n", sizeof(unsigned char));

    unsigned char a;

    a = 0;

    printf("%d\n", a - 1); 
    printf("%u\n", a - 1); 
    printf("%lu\n", a - 1); 
    printf("%llu\n", a - 1);   
    printf("%zu\n", a - 1); 

    return 0;
}

輸出是

unsigned char has 1 bytes.
-1
4294967295
4294967295
4294967295 
4294967295

4294967295是2 ^ 32 - 1

我哪里做錯了?

首先,當您將小於int的整數參數傳遞給可變參數函數(如printf )時,它會自動提升為int

其次,當您使用算術時,較小的整數類型將再次提升為int

有關詳細信息,請閱讀此隱式轉換參考

如果要打印char (或者更確切地說是unsigned char )值,則需要使用格式說明符的hh前綴(請參閱printf和系列引用 ):

printf("%hhu\n", (unsigned char) (a - 1));
a-1

這是算術運算並且發生隱式轉換。 編譯器會將其視為整數。 嘗試將-1分配給無符號類型,然后檢查該值。 您還應該注意到printf操作數,例如%d,對於該特定示例,它應該是整數。

您的知識在細微方面是不完整的:

我的編譯器的unsigned char包含1個字節。

根據定義,類型unsigned char恰好是所有編譯器的一個字節。

所以據我所知,unsigned char的范圍是0到2 ^ 8 - 1,即255

不完全是: unsigned char最小值位數為8並且此類型不允許填充位,這意味着一個字節最小大小為8位。 實際上,現在大多數架構都標准化為8位字節,但C標准允許其他更大的位寬,而一些微控制器則使用16位字節(甚至32位字節)。 在這樣的處理器上, unsigned char為16位(甚至32位)。

現在我想確認unsigned char的最大整數可以顯示為255

這是一個真正的問題,可以在編譯時和運行時進行驗證。

以下是我的代碼:

 #include <stdio.h> #include <limits.h> 

包括<limits.h>是一種很好的方法: UCHAR_MAX是您要在預處理指令中打印甚至直接測試的值。

 int main(void) { printf("unsigned char has %d bytes.\\n", sizeof(unsigned char)); 

未定義的行為: %d需要int類型的參數,該參數與size_t類型的sizeof(unsigned char)不同且可能不兼容。 使用%zu或將參數轉換為(int)sizeof(unsigned char) 但請注意, 按定義sizeof(unsigned char) 的值始終為1 ,類型為size_t

  unsigned char a; a = 0; printf("%d\\n", a - 1); 

a - 1總是求值為-1因為a被提升為int0 - 1的值為-1 你想要打印(unsigned char)(a - 1) ,或簡單地(unsigned char)-1

  printf("%u\\n", a - 1); 

這將打印(unsigned int)-1的值,即UINT_MAX ,而不是UCHAR_MAX

  printf("%lu\\n", a - 1); printf("%llu\\n", a - 1); printf("%zu\\n", a - 1); 

上面的3個printf調用具有潛在的未定義行為,因為為預期字節分別為unsigned longunsigned long longsize_t的參數傳遞int值。

  return 0; } 

這是一個更簡單的方法:

#include <stdio.h>
#include <limits.h>

int main() {
    printf("UCHAR_MAX = %u\n", UCHAR_MAX);
    printf("(unsigned char)-1 = %u\n", (unsigned char)-1);
    printf("-1 with %%hhu conversion: %hhu\n", -1);
    return 0;
}

輸出:

UCHAR_MAX = 255
(unsigned char)-1 = 255
-1 with %hhu conversion: 255

您的代碼調用了未定義的行為,因為您使用了錯誤的printf格式說明符。

GCC編譯器警告:

prog.c: In function 'main':
prog.c:5:32: warning: format '%d' expects argument of type 'int', but argument 2 has type 'long unsigned int' [-Wformat=]
     printf("unsigned char has %d bytes.\n", sizeof(unsigned char));
                               ~^            ~~~~~~~~~~~~~~~~~~~~~
                               %ld
prog.c:13:15: warning: format '%lu' expects argument of type 'long unsigned int', but argument 2 has type 'int' [-Wformat=]
     printf("%lu\n", a - 1);
             ~~^     ~~~~~
             %u
prog.c:14:16: warning: format '%llu' expects argument of type 'long long unsigned int', but argument 2 has type 'int' [-Wformat=]
     printf("%llu\n", a - 1);
             ~~~^     ~~~~~
             %u
prog.c:15:15: warning: format '%zu' expects argument of type 'size_t', but argument 2 has type 'int' [-Wformat=]
     printf("%zu\n", a - 1);
             ~~^     ~~~~~
             %u

C11 $ 7.19.6.1 p9:

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

暫無
暫無

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

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