问题1:
“当我们赋给无符号类型一个超出它表示范围的值时,结果是初始值对无符号类型表示数值总数取模后的余数”这句话怎么理解?比如把-1赋给8bit大小的无符号char所得的结果为何是255?
我的理解是这样:假如-1=11111111(第一个1表示负),当把其表示为无符号时则11111111=255
那么为什么赋给带符号类型一个超出它表示范围的值时结果是未定义?
问题2
当算术表达式中同时出现有符号和无符号类型时,有符号类型的值是正数时转换成无符号后的值是否和转换前一样?比如int a=1,unsigned b=1,输出a+b时a会先转换成无符号,转换后的还a等于1么?如果int a=-1,unsingned b=2,输出a+b时a会先转换成无符号类型,转换后的a等于几?
问题2:
如图第四个长注释。
书上说的意思是,不管a+b的结果是什么,只要a和b一个是无符号一个是带符号,就要先把带符号那个转换成无符号再执行加法。而我实际运行了图中的程序后我认为是只有当a+b的结果是负数且a和b一个是带符号一个不带符号时,才把结果转为无符号。
到底哪种才是对的?
巴扎黑2017-06-19 09:09:29
问题1
其实解释上面说的复杂了,你如果从内存的角度来看,就会发现很简单。无符号和有符号的区别不在于内存的存储,而在于内存的获取。比如你举例的-1赋值8bit的例子,如果是无符号,那么只会填充最后8个二进制位,其余的会被抛弃掉。因为这个8bit是无符号,所以这里面所有的二进制位都表示数字,所以是255。但是如果是有符号的8bit,其中首位二进制表示符号位,但是赋值的时候,-1的符号位并没有成为8bit数据的符号位,所以8bit数据的符号位其实是无效的,所以这个赋值也就出错了。那句话的意思是(-1)%256=255,其中256是无符号8bit的总数(或者说是范围)。
问题2
上面说过了,其实有符号和无符号的存储方式是相同的,只是读取方式不同。有符号的会把首位当做符号位,无符号的会把首位当做数字位。在内存中是一样的,你的例子中,第一次a + b的结果,用二进制表示是一堆1。如果你直接输出,由于转成了unsigned,也就是两个unsigned相加,结果是unsigned,那一堆1的二进制作为unsigned输出是4294967295,但是如果把a+b赋值给了sum,sum存储值的时候内存里依旧是一堆1,但是由于sum是有符号int,读取的时候,首位被当做了符号位,所以读出来的值是-1。
所以你问题2里面,并不是在运算时候没有转换,而是因为数值存储时候只考虑二进制,这个对于有无符号并无差别。只有在读取的时候才去判断符号位,所以才导致了输出结果的差异。