unsigned char 的否定运算符
Negation operator on unsigned char
#include <stdio.h>
int main() {
unsigned char a = 5;
printf("%d\n",~a);
printf("%d\n",a=~a);
return 0;
}
根据这里接受的答案 ,在第一个 printf 中,a
应该提升为 int
并且输出应该是一个大的负数。但是第一个 printf 的输出是 -6。你能解释一下为什么输出是 -6 以及为什么在这种情况下 char 没有提升为 int 吗?
Can you please explain why the output is -6 and why the char is not promoted to int in this case?
不是真的,因为它 是 被提升为 int
- 而且,作为 int
,反转所有位将(假设 two's-complement notation 且没有溢出)将正值 n
转换为负值,-(n+1)
.
对您的代码进行的这种修改可以证明正在发生的事情:
#include <stdio.h>
int main()
{
int a = 5;
printf("%d\n", ~a); // Prints -6
printf("%d\n", a = (unsigned char)~a); // Prints 250 - lower 8 bits of the int
return 0;
}
它正在升级并且 ~5 == -6
是二进制补码。假设二进制补码,一个小的正数的按位求反将产生一个小的负数。只有当被视为 unsigned
时,该数字才会显得很大,这就是链接答案中的 "%X"
所做的。
(顺便说一句,链接答案中的数字也应该在打印为 "%X"
之前转换为 unsigned
,因为 printf
在技术上要求转换说明符和传递参数的类型)。
对于二进制补码内部表示,如果您有一个整数值x
,则表达式
x + ~x + 1
等于0。
所以对于这个声明
unsigned char a = 5;
表达式 ~a
的操作数将被提升为 int 类型。
所以你会得到那个
~a + a + 1 = 0
即
~a + 5 + 1 = 0
因此表达式的值 ~a
~a = -5 -1 = -6
用二进制表示是这样的(前提是int类型占4个字节)
a ( = 5 ) = 00000000 00000000 00000000 00000101
~a = 11111111 11111111 11111111 11111010
a + ~a = 11111111 11111111 11111111 11111111
最后一个二进制值是-1
在int类型中的表示。
在本次通话中
printf("%d\n",a=~a);
起初表达式 ~a 由于赋值而被截断为 unsigned char 类型的对象
a=~a
即表达式将有一个非负数。
#include <stdio.h>
int main() {
unsigned char a = 5;
printf("%d\n",~a);
printf("%d\n",a=~a);
return 0;
}
根据这里接受的答案 a
应该提升为 int
并且输出应该是一个大的负数。但是第一个 printf 的输出是 -6。你能解释一下为什么输出是 -6 以及为什么在这种情况下 char 没有提升为 int 吗?
Can you please explain why the output is -6 and why the char is not promoted to int in this case?
不是真的,因为它 是 被提升为 int
- 而且,作为 int
,反转所有位将(假设 two's-complement notation 且没有溢出)将正值 n
转换为负值,-(n+1)
.
对您的代码进行的这种修改可以证明正在发生的事情:
#include <stdio.h>
int main()
{
int a = 5;
printf("%d\n", ~a); // Prints -6
printf("%d\n", a = (unsigned char)~a); // Prints 250 - lower 8 bits of the int
return 0;
}
它正在升级并且 ~5 == -6
是二进制补码。假设二进制补码,一个小的正数的按位求反将产生一个小的负数。只有当被视为 unsigned
时,该数字才会显得很大,这就是链接答案中的 "%X"
所做的。
(顺便说一句,链接答案中的数字也应该在打印为 "%X"
之前转换为 unsigned
,因为 printf
在技术上要求转换说明符和传递参数的类型)。
对于二进制补码内部表示,如果您有一个整数值x
,则表达式
x + ~x + 1
等于0。
所以对于这个声明
unsigned char a = 5;
表达式 ~a
的操作数将被提升为 int 类型。
所以你会得到那个
~a + a + 1 = 0
即
~a + 5 + 1 = 0
因此表达式的值 ~a
~a = -5 -1 = -6
用二进制表示是这样的(前提是int类型占4个字节)
a ( = 5 ) = 00000000 00000000 00000000 00000101
~a = 11111111 11111111 11111111 11111010
a + ~a = 11111111 11111111 11111111 11111111
最后一个二进制值是-1
在int类型中的表示。
在本次通话中
printf("%d\n",a=~a);
起初表达式 ~a 由于赋值而被截断为 unsigned char 类型的对象
a=~a
即表达式将有一个非负数。