常量32768和0x8000之间的类型区别可以有所不同吗?

标准规定hex常量如0x8000(大于有符号整数)是无符号的(就像八进制常量一样),而像32768这样的十进制常量是长符号。 (确切类型假定为16位整数和32位长。)但是,在常规C环境中,两者将具有相同的表示forms,二进制1000 0000 0000 0000 。 这种差异真的会产生不同的结果吗? 换句话说,这种差异是否很重要?

是的,这很重要。 如果您的处理器具有16位int和32位long类型,则32768具有long类型(因为32767是符合有符号16位int的最大正值),而0x8000(因为它也被认为是unsigned int )仍然适合16位unsigned int

现在考虑以下程序:

 int main(int argc, char *argv[]) { volatile long long_dec = ((long)~32768); volatile long long_hex = ((long)~0x8000); return 0; } 

当32768被认为是long ,否定将反转32位,从而产生类型为long的表示0xFFFF7FFF; 演员是多余的。 当0x8000被认为是unsigned int ,否定将反转16位,从而产生带有unsigned int类型的表示0x7FFF; 然后,强制转换将零扩展为0x00007FFF的long值。 请看H&S5,第24页第2.7.1节。

最好用UULL适当增加常数。

在64位long的32位平台上,以下代码中的ab将具有不同的值:

 int x = 2; long a = x * 0x80000000; /* multiplication done in unsigned -> 0 */ long b = x * 2147483648; /* multiplication done in long -> 0x100000000 */ 

还没有给出另一个检查:比较(大于或小于运算符)-1到32768和0x8000。 或者,就此而言,尝试将它们中的每一个与等于-32768的’int’变量进行比较。

假设int是16位, long是32位(这些天实际上很不寻常; int通常是32位):

 printf("%ld\n", 32768); // prints "32768" printf("%ld\n", 0x8000); // has undefined behavior 

在大多数情况下,数值表达式将隐式转换为由上下文确定的适当类型。 (但这并不总是你想要的类型。)这不适用于可变参数函数的非固定参数,例如格式字符串后面的*printf()函数之一的任何参数。

不同的是,如果您尝试向16位int添加一个值,它将无法执行此操作,因为它将超出变量的边界,而如果您使用32位长,则可以添加任何数字它不到2 ^ 16。