如何确定变量是已签名还是未取消

use*_*437 5 c unsigned

在C程序中,如果是整数signed integer,那么最高位是1,否则0.

让我们charunsigned char,对于一个范围signed char-128,以127unsigned char0255,但其实他们的十六进制处于区域0x000xff.我现在的问题是,如果一个charunsigned 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吗?

glg*_*lgl 6

printf()调用(和其他场合)时,适用整数提升规则。

编译器将给定值转换为int. 这种情况的发生取决于 char 的符号(当然,编译器知道)。因此,根据 char 的符号,编译器通过填充0位或 char 的最高位来进行转换。


Jen*_*ens 6

这里有许多相关问题,例如这个问题.

你的问题不太正确:因为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在这种情况下可能对您有意义.