Ree*_*Ree 6 c operators unary-operator
在K&R ANSI C书中,A.7.4.5节(一元减法运算符)中说明:
...无符号数量的负数是通过从提升类型的最大值中减去提升值并加1来计算的; ...
这究竟是如何计算出来的?你能举一个简短的例子吗?
我不知道这怎么会产生200u的负数:从任何整数类型(有符号或无符号)的最大值减去200,并且加1不会导致-200.
我知道一元减去了什么 - 问题是我没有看到根据描述如何计算结果.
无符号值不能为负数,因此-200不是可能的结果.
它的含义是,如果UINT_MAX你的系统是65535,那么结果是:
unsigned a = 200;
unsigned b = -a;
long c = -a;
Run Code Online (Sandbox Code Playgroud)
会留下两个65336 b和c.
如果你的系统有UINT_MAX > LONG_MAX(通常是因为int和long大小都一样),你将需要使用long long的c(但请注意有没有甚至没有任何保证,这是足够长的时间).
这个细节(否定无符号数的结果是另一个,必然是正数,无符号数)如果你不理解它会导致一些意想不到的效果.例如,在此代码中,第一个示例打印,"true"但第二个示例打印"false":
int a = 200;
unsigned b = 200;
if (-a < 100) printf("true\n"); else printf("false\n");
if (-b < 100) printf("true\n"); else printf("false\n");
Run Code Online (Sandbox Code Playgroud)
(请注意,我们不会将否定运算符的结果存储在任何地方 - 这不是问题).
显然你错过了你引用的描述中的unsigned这个词.这是本案的关键词.在C语言中,无符号数量的"负数" 仍然是无符号的,这意味着它不是真正的负数.根据定义,无符号值不能是负数.它们总是正数或0. C中无符号值的算术是模运算,或者简单来说,当你对它们执行算术运算时,无符号量"环绕".一元否定也不例外.计算-n何时n无符号与计算无异0 - n.如果n是unsigned int和它的值是200预期的结果不是-200,而是UINT_MAX - 200 + 1,这正是引用告诉你的.
它描述了实现模运算的操作,即它计算一个值
a + (-a) == 0
Run Code Online (Sandbox Code Playgroud)
这使得否定的无符号数与否定的有符号数密切相关.
在数字表示为二进制补码的机器上(例如x86),只需将无符号数的位模式视为普通有符号数,并使用机器的标准"否定"指令即可.