int和unsigned int类型数字加减问题
- C/C++ code
unsigned int a = 6;int b = -20;(a+b > 6) ? puts(">6") : puts("<=6");
高手们帮我分析一下这个过程,int类型和unsigned int 类型的数加减时,是怎么互相转换的?
[解决办法]
1)(a+b)会隐式转换成int。
2)编程实践部建议这样写,需要转换的时候应该自己强制转换。
[解决办法]
>6
((unsigned int)a+b > 6) ? puts(">6") : puts("<=6");
[解决办法]
>6
(unsigned int (a+b) > 6) ? puts(">6") : puts("<=6");
[解决办法]
类型提升,int---->unsigned int ,所以a+b按(unsigned int)a + (unsigned int)b
a值不变,而b(保形---二进制码不变)----按unsigned int类型解读二进制码----2^32-20为大正数)
[解决办法]
3.2.1.5 Usual arithmetic conversions
Many binary operators that expect operands of arithmetic type cause conversions and yield result types in a similar way. The purpose is to yield a common type, which is also the type of the result. This pattern is called the usual arithmetic conversions: First, if either operand has type long double, the other operand is converted to long double. Otherwise, if either operand has type double, the other operand is converted to double. Otherwise, if either operand has type float, the other operand is converted to float. Otherwise, the integral promotions are performed on both operands. Then the following rules are applied: If either operand has type unsigned long int, the other operand is converted to unsigned long int. Otherwise, if one operand has type long int and the other has type unsigned int, if a long int can represent all values of an unsigned int, the operand of type unsigned int is converted to long int ; if a long int cannot represent all the values of an unsigned int, both operands are converted to unsigned long int. Otherwise, if either operand has type long int, the other operand is converted to long int. Otherwise, if either operand has type unsigned int, the other operand is converted to unsigned int. Otherwise, both operands have type int.
The values of operands and of the results of expressions may be represented in greater precision and range than that required by the type; the types are not changed thereby.
[解决办法]
类型提升问题,我个人觉得许多教程讲不清楚
1.保值变换,如(2+0.3),整型的2变换为double的2.0,值不变而二进制码变了
2.保形变换,如(-2+6U),int (-2)保值无法在unsigned int范围内表示,就保持原有二进制码形式,按unsigned int类型解读为(2^32-2)U
[解决办法]
unsigned int a = 6;
int b = -20;
在内存里面
a:0x 00 00 00 06 换成二进制:00000000 00000000 00000000 00000110
b: 0x ff ff ff ed 换成二进制:11111111 11111111 11111111 11101100
a+b > 6 之后的结果为:
(a + b) 0x ff ff ff f2 换成二进制为:11111111 11111111 11111111 11110010
当一个int和unsigned int进行运算时,会将int转换为unsigned int。
运算结果为:unsigned int
0x ff ff ff f2 表示的 unsigned int 为:9294967282
楼主不要忘记给分呀。
[解决办法]
VC调试(TC或BC用TD调试)时按Alt+8、Alt+6和Alt+5,打开汇编窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应内存和寄存器变化,这样过一遍不就啥都明白了吗。
对VC来说,所谓‘调试时’就是编译连接通过以后,按F10或F11键单步执行一步以后的时候,或者在某行按F9设了断点后按F5执行停在该断点处的时候。
(Linux或Unix下可以在用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。)
提醒:
“学习用汇编语言写程序”
和
“VC调试(TC或BC用TD调试)时按Alt+8、Alt+6和Alt+5,打开汇编窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应内存和寄存器变化,这样过一遍不就啥都明白了吗。
(Linux或Unix下可以在用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。)”
不是一回事!
不要迷信书、考题、老师、回帖;
要迷信CPU、编译器、调试器、运行结果。
并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。
任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实!
有人说一套做一套,你相信他说的还是相信他做的?
其实严格来说这个世界上古往今来所有人都是说一套做一套,不是吗?
不要写连自己也预测不了结果的代码!
[解决办法]
我是7楼的,下面程序证明我的分析OK,记得给分。
- C/C++ code
#include <stdio.h>int main(){ unsigned int a = 6; int b = -20; printf("%d\n", (a + b)); printf("%u\n", (a + b)); printf("0x%x\n", (a + b)); (a+b > 6) ? puts(">6") : puts("<=6");}
[解决办法]
既然 a + b 的结果是 0xff ff ff f2了 二进制就是 11111111 11111111 11111111 11110010。
上面二进制的无符号就是 4294967282 呀。
至于怎么算的参考下面:
(0xff * 256 * 256 * 256) + (0xff * 256 * 256) + (0xff * 256) + (0xf2) = 0xfffffff2
第一个ff 第二个ff 第三个ff f2
4278190080 + 16711680 + 65280 + 242 = 4294967282
给分呀,再不给分不理你了。
[解决办法]
4294967282主要是 你的 说明符%u导致的。编译器不会帮助你转换类型。
[解决办法]
32位太长了,用8位示例:
8位二进制码,表示unsighed int的值范围是0----255,即0----2^8-1
表示int的值范围是-128----127,即-2^7----2^7-1
现有int值-6,其二进制值码为11111010,按unsighed int计值为250,即2^8-6