在C程序中,如果是整数signed integer
,那么最高位是1
,否则0
.
让我们char
和unsigned char
,对于一个范围signed char
是-128
,以127
和unsigned char
为0
对255
,但其实他们的十六进制处于区域0x00
来0xff
.我现在的问题是,如果一个char
并unsigned char
存储在使用8位二进制数记忆,如何计算机本身知道它是否signed
还是unsigned
?
char a = 0xff; printf("%d", a); //its result is -1.
unsigned char a = 0xff; printf("%d", a); //its result is 255.
Run Code Online (Sandbox Code Playgroud)
在上面的例子中,如何printf
知道0xff
有符号或无符号的值?这只取决于定义a
吗?
在printf()
调用(和其他场合)时,适用整数提升规则。
编译器将给定值转换为int
. 这种情况的发生取决于 char 的符号(当然,编译器知道)。因此,根据 char 的符号,编译器通过填充0
位或 char 的最高位来进行转换。
这里有许多相关问题,例如这个问题.
你的问题不太正确:因为signed
最高位并非总是如此1
- 只有当值为负时.事实上,signed
或者unsigned
是归属于完全相同的位模式的"类型",以及在比较或提升时如何解释这些位模式由它们各自的类型定义.
例如:
unsigned char u = 0xFF; // decimal 255
signed char s = 0xFF; // decimal -1
Run Code Online (Sandbox Code Playgroud)
您可以在设置的最高位中看到两个值是如何相同的,但它们的类型不同.
编译器使用类型系统来了解如何解释值,程序员的任务是为值分配有意义的类型.在上面的例子中,我告诉编译器第一个0xFF
应该被解释为一个unsigned
值(参见include文件limits.h),其最大范围是:
u = 0x00; // decimal 0, CHAR_MIN
u = 0xFF; // decimal 255, UCHAR_MAX
Run Code Online (Sandbox Code Playgroud)
第二个0xFF
作为signed
具有最大范围的值:
s = 0x00; // decimal 0, CHAR_MIN
s = 0x7F; // decimal 127, SCHAR_MAX
s = 0x80; // decimal -127, SCHAR_MIN (note how 0x7F + 1 = 0x80, decimal 127 + 1 = -127, called an overflow)
s = 0xFF; // decimal -1
Run Code Online (Sandbox Code Playgroud)
对于示例中的printf,%d
告诉它signed int
期望值.根据C语言的整数提升规则,较小的char
类型是符号扩展(如果是signed
类型)或零扩展(如果是unsigned
类型).完成上面的例子:
printf("%d", u); // passes a int 0x000000FF, decimal 128, to the function
printf("%d", s); // passes a int 0xFFFFFFFF, decimal -1, to the function
Run Code Online (Sandbox Code Playgroud)
这里有更多printf格式说明符,例如%u
在这种情况下可能对您有意义.
归档时间: |
|
查看次数: |
1443 次 |
最近记录: |