整数文字的类型和〜在C中

use*_*967 20 c integer literals bitwise-operators

我是C初学者,我对C答案书中的以下示例感到困惑.

在系统中查找unsigned long long大小的一种方法是键入:

printf("%llu", (unsigned long long) ~0);
Run Code Online (Sandbox Code Playgroud)

我不知道为什么这个语法有效?

在我的系统上,int是32位,long long是64位.
我所期望的是,因为0是一个整数类型的常量,~0计算一个32位整数的否定,然后unsigned long long由转换运算符转换为a .结果应该给出2 32 - 1.

不知何故,看起来~运营商已经知道它应该在64位上运行?
编译器是否将此指令解释为printf("%llu", ~(unsigned long long)0);?自演员表演以来听起来并不正确并~具有相同的优先权.

das*_*ght 13

不知何故,看起来〜运算符已经知道它应该作用于64位?

这不是~运营商,而是演员.以下是根据标准完成整数转换的方法:

6.3.1.3有符号和无符号整数

  • 当具有整数类型的值转换为除_Bool之外的另一个整数类型时,如果该值可以由新类型表示,则它将保持不变.
  • 否则,如果新类型是无符号的,则通过重复地添加或减去一个可以在新类型中表示的最大值来转换该值,直到该值在新类型的范围内.
  • 否则,新类型将被签名,并且值无法在其中表示; 结果是实现定义的,或者引发实现定义的信号.

signed的值int ~0对应-1于具有负值的二进制补码表示的系统.它不能用a表示unsigned long long,因此第一个要点不适用.

第二个项目符号确实适用:新类型是无符号的,因此MAXunsigned long long其添加到-1一次以将结果输入到范围中unsigned long long.这与符号扩展-1到64位具有相同的效果.


Win*_*ute 5

0是类型int,而不是unsigned int.~0因此(在使用二进制补码整数表示的机器上,这就是今天使用的所有)是-1,而不是2 32 - 1.

假设一个64位unsigned long long,(unsigned long long) -1则是-1模2 64,即2 64 - 1.