KEEP K.I.S.S.

tk's blog

C 语言中的位取反操作符

tk posted @ Apr 24, 2012 02:54:07 PM in C with tags 读书 位操作符 , 3888 阅读

话不多说,先来看一段代码:

 

 1 #include <stdio.h>
 2 
 3 int main(int argc, char *argv[])
 4 {
 5         unsigned char uc = 0x1f;
 6         unsigned int ui = ~uc;
 7         unsigned long long ull = ~uc;
 8 
 9         unsigned char cc = ~uc;
10         printf("uc = %#x\n", uc);
11         printf("cc: ~uc = %#x\n", cc);
12         printf("ui: ~uc = %#x\n", ui);
13         printf("ull: ~uc = %#llx\n", ull);
14         return 0;
15 }

因为用到了 C99 标准的 long long 类型,所以编译时候需要添加 "-std=c99" 选项:

gcc -Wall -std=c99 -o file file.c

输出结果(x86 mingw32):

 

uc = 0x1f
cc: ~uc = 0xe0
ui: ~uc = 0xffffffe0
ull: ~uc = 0xffffffffffffffe0
 
这里显现出了 位取反 操作的结果特殊性,对于通常而言,我们以为一个 unsigned char 位取结果的类型也应该是 unsigned char ,也就是说当我们把这个结果赋给一个 unsigned int (或者 unsigned long long)类型的值时候,这个值也应该是 不会超过 unsigned char 的取值范围的。但是上述代码显示出并非这样的情况。
 
上述代码显示出把 unsigned char 位取反值赋给 unsigned int 变量时,除了低位字节是补码外,高位字节都是 0 的补码 1了。对于赋值给 unsigned long long 变量也是如此。
 
我个人理解的解释是,在 x86-32 的机器上,机器字长为 32,寄存器长度也是32,对于像 unsigned char 这样的 1 byte 的值,运算时会存储在寄存器中的低位字节,高位字节都为0,然后位取反操作指令会对整个寄存器的值位取反,然后赋值给 unsigned int (4 bytes)这样的变量时,是将整个寄存器值取出。这样高位字节都会是 0 的补码 1。但是这样怎么解释赋值给 unsigned long long 类型变量发生的情况呢?或者说对于位取反操作的结果是个特殊状态的值?
 
PS: 最近在看 CSAPP(《深入理解计算机系统》)第二版,其中在做练习题 2.12 发现了上述情形,之前不知道,所以就研究了一下下,不过还是半解。。。。
vx13 说:
Apr 24, 2012 08:45:35 PM

我查了一下,根据 c99 标准 6.3.1.1 节的说明,似乎对于级别比 int 和 unsigned int 低的整型变量,只要其范围是 int 的子区间,都会隐式强转为 int 来参与运算。
"If an int can represent all values of the original type, the value is converted to an int;
otherwise, it is converted to an unsigned int. These are called the integer
promotions.48) All other types are unchanged by the integer promotions.
"

vx13 说:
Apr 24, 2012 08:48:29 PM

http://learn.akae.cn/media/ch15s03.html
这里有该特性的中文介绍和使用示例。

tisyang 说:
Apr 25, 2012 08:35:37 AM

@vx13: 但是 对于 转换成 long long 那里的区别还是一知半解状态

vx13 说:
Apr 25, 2012 09:12:50 AM

@tisyang: 那个是赋值的问题。把 int 型的 -1 赋给 unsigned long long 的变量,就会变成一堆 f 的。

NCERT Urdu Question 说:
Sep 22, 2022 09:18:21 PM

One of the language courses that has been established in all Urdu medium schools is Urdu. Learn how to speak, read, and write the Urdu language in the 8th grade by following the Urdu Education school's syllabus and curriculum. NCERT Urdu Question Paper Class 8 STD-8 students gain a lot from learning Urdu. Their intelligence is increased, and their character is strengthened. Like any other topic, it is essential to studying Urdu.


登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter