Frage 1:
Wie verstehen Sie den Satz „Wenn wir einem vorzeichenlosen Typ einen Wert zuweisen, der seinen Darstellungsbereich überschreitet, ist das Ergebnis der Rest des Anfangswerts modulo der Gesamtzahl der durch den vorzeichenlosen Typ dargestellten Werte.“ ? Warum ist beispielsweise das Ergebnis der Zuweisung von -1 zu einem 8-Bit-Zeichen ohne Vorzeichen 255?
Mein Verständnis ist folgendes: Wenn -1=11111111 (die erste 1 steht für negativ), wenn es als vorzeichenlos ausgedrückt wird, 11111111=255
Warum führt die Zuweisung eines vorzeichenbehafteten Typs zu einem Wert, der seinen Darstellungsbereich überschreitet?
Frage 2
Wenn sowohl vorzeichenbehaftete als auch vorzeichenlose Typen in einem arithmetischen Ausdruck vorkommen und der Wert des vorzeichenbehafteten Typs eine positive Zahl ist, ist der Wert nach der Konvertierung in vorzeichenlosen Typ derselbe wie vor der Konvertierung? Wenn beispielsweise int a = 1 und vorzeichenloses b = 1 sind, wird a bei der Ausgabe von a + b zuerst in vorzeichenlos konvertiert. Wird a nach der Konvertierung gleich 1 sein? Wenn int a = -1, vorzeichenlos b = 2, wird a bei der Ausgabe von a + b zuerst in einen vorzeichenlosen Typ konvertiert. Was ist der Wert von a nach der Konvertierung?
Frage 2:
Wie im vierten langen Kommentar im Bild gezeigt.
Was das Buch sagt, ist, dass unabhängig vom Ergebnis von a+b, solange eines von a und b ohne Vorzeichen und das andere mit Vorzeichen ist, das vorzeichenbehaftete in ein vorzeichenloses umgewandelt werden muss, bevor die Addition durchgeführt wird. Nachdem ich das Programm im Bild tatsächlich ausgeführt habe, dachte ich, dass das Ergebnis nur dann in ein vorzeichenloses Ergebnis konvertiert wird, wenn das Ergebnis von a + b eine negative Zahl ist und einer von a und b vorzeichenbehaftet und der andere vorzeichenlos ist.
Welches ist richtig?
问题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里面,并不是在运算时候没有转换,而是因为数值存储时候只考虑二进制,这个对于有无符号并无差别。只有在读取的时候才去判断符号位,所以才导致了输出结果的差异。