[英]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
被提升為int
, 0 - 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 long
, unsigned long long
和size_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.