7

我对以下代码感到很困惑:

#include <stdio.h>
#include <stdint.h>

int main(int argc, char ** argv)
{
    uint16_t a = 413;
    uint16_t b = 64948;

    fprintf(stdout, "%u\n", (a - b));
    fprintf(stdout, "%u\n", ((uint16_t) (a - b)));

    return 0;
}

返回:

$ gcc -Wall test.c -o test
$ ./test
4294902761
1001
$ 

似乎表达式 (a - b) 的类型为 uint32_t。我不明白为什么,因为两个运算符都是 uint16_t。

谁能给我解释一下?

4

3 回答 3

16

C 标准非常清楚地解释了这一点(§6.5.6 加法运算符):

如果两个操作数都具有算术类型,则对它们执行通常的算术转换。

(§6.3.1.8 通常的算术转换):

...整数提升在两个操作数上执行。

(§6.3.1.1 布尔值、字符和整数):

如果 anint可以表示原始类型的所有值,则将该值转换为int; ...这些被称为整数促销。整数提升不会改变所有其他类型。

因为可以表示您平台上的int所有值,并在执行减法之前转换为。结果具有 type ,并作为传递给。您已使用参数指定了格式化程序;严格来说,这会调用未定义的行为,但在您的平台上,该参数被解释为它的二进制补码表示,并被打印出来。uint16_tabintintprintfint%uintint

于 2011-10-31T14:11:55.983 回答
1

如果你丢弃一个数字的最高位(通过显式转换为 16 位无符号整数),那么你将得到一个小于(在 0 和 2^16-1 范围内)的结果前。

于 2011-10-31T14:17:41.393 回答
0

unsigned intC在进行减法之前将参数提升到。这是标准行为。

例如,请参见在存在 unsigned int 和 signed int 的 C 表达式中,哪种类型将提升为哪种类型?详情。

于 2011-10-31T14:03:12.137 回答