数据类型修饰符和移位运算符

时间:2012-07-25 04:18:49

标签: c

int main(void)  
{  

   unsigned i = -23; // line 1
   short a, b = 0x1;

   printf("sizeof(short) = %i\n", (int)sizeof(short)); // line 2

   a = b << 31; // line 3
   printf("i = %i", i); // line 4
   printf("i = %u", i); // line 5

   return 0;
}

为什么第1行在指定类型修饰符unsigned时没有给出任何错误?

第2行在我的系统中将sizeof(short)打印为2个字节。 a&amp; b是短整数,因此是2个字节或16位长。但第3行不会引发任何错误。当字长仅为16位时,如何左移31位

第4行和第5行是否有隐式转换?

我在64位Mac上使用GCC编译器。

3 个答案:

答案 0 :(得分:6)

  1. 您没有收到错误,因为负整数常量被隐式转换为无符号值,变为非常大的数字(MSB设置为1)
  2. 将值隐式转换为int 1,2 ,移位并分配回来;当数字转换回short时,你得到全零,但这是一个未定义的行为 3
  3. C语义中第4行和第5行没有转换;与将参数传递给可变参数函数相关联的常规类型促销确实适用。但是,printf在第4行重新解释unsigned as singed:格式说明符是告诉printf传递给它的参数类型的唯一内容。

  4. 1 转移前的促销活动:link

    2 整数促销活动:link

    3 移动30就可以了,因为2^30可以表示为int

答案 1 :(得分:2)

1)根据C99 6.3.1.3的第2点添加UINT_MAX + 1,将负整数转换为无符号:

 6.3.1.3 Signed and unsigned integers
 [...]
 2 Otherwise, if the new type is unsigned, the value is converted by repeatedly
 adding or subtracting one more than the maximum value that can be represented
 in the new type until the value is in the range of the new type.

2)根据C99 6.5.7

将位移运算符的操作数隐式转换为int
6.5.7 Bitwise Shift Operators
1 Each of the operands shall have integer type.
2 The integer promotions are performed on each of the operands.
3 The type of the result is that of the promoted left operand.

3)见dasblinkenlight的答案。

答案 2 :(得分:0)

分配:您为变量提供的类型没有说明您可以放在哪里,但编译器应该如何解释它。在你的情况下,-23被'转换'为32位,然后这个值被放到unsigned int(也有32位)......(位长度取决于架构)

http://en.wikipedia.org/wiki/Two%27s_complement

移位:移位时,一侧的位“消失”,另一侧的位(零)必须移入。您可以将变量移动多少次。

Printfing :同样,这不是关于'转换',而是关于一系列位的'解释'。