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

时间:2011-11-09 18:09:12

标签: c language-lawyer

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

5 个答案:

答案 0 :(得分:7)

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

现在考虑以下计划:

unsigned int

当32768被认为是int main(int argc, char *argv[]) { volatile long long_dec = ((long)~32768); volatile long long_hex = ((long)~0x8000); return 0; } 时,否定将反转32位, 导致表达式为0xFFFF7FFF,类型为long;演员是 多余。 当0x8000被视为long时,否定将反转 16位,产生类型unsigned int的表示0x7FFF; 然后,强制转换将零扩展到unsigned int值0x00007FFF。 请看H& S5,第27.1页第24页第24页。

最好根据需要使用longUUL来增加常量。

答案 1 :(得分:1)

在具有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 */

答案 2 :(得分:1)

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

答案 3 :(得分:1)

假设int是16位且long是32位(这些天实际上相当不寻常; int更常见的是32位):

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

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

答案 4 :(得分:0)

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