return1在c语言中是什么意思 1在c语言中是什么意思( 二 )


有符号数到无符号数的隐式强制类型转换导致了某些非直观的行为 。而这些非直观的特性经常导致程序错误,并且这种包含隐式强制类型转换的细微差别的错误很难被发现 。
4 扩展一个整型数字的位表示一个常见的运算是在不同字长的整数之间转换,同时又保持数值不变 。
对于有符号整数和无符号整数,两者在扩展时,高位的符号扩展有所区别:
short sx = val; /* -12345 */unsigned short usx = sx; /* 53191 */int x = sx; /* -12345 */unsigned ux = usx; /* 53191 */在采用补码表示的32 位大端法机器上的内存布局:

return1在c语言中是什么意思  1在c语言中是什么意思

文章插图
有符号整型使用1来做符号扩展 。
无符号整型使用0来做符号扩展 。
return1在c语言中是什么意思  1在c语言中是什么意思

文章插图
有符号整数在做右移运算时,也会存在符号扩展的问题 。
5 截断数字假设我们不用额外的位来扩展一个数值,而是减少表示一个数字的位数 。例如下面代码中这种情况:
int x = 53191;short sx = (short) x;/* -12345 */int y = sx;/* -12345 */当我们把x 强制类型转换为short 时,我们就将 32 位的int 截断为了 16 位的short int 。
return1在c语言中是什么意思  1在c语言中是什么意思

文章插图
当将一个w位的整型数截断为一个k位整型数字时,我们会丢弃高w-k位 。
无符号整数取模:
有符号整数的补码取模后要做转换 :
6 整数运算与溢出C语言的整型数字是一个有限字长的表示,当在计算时存在溢出时,会做模运算处理 。
当两个w位的无符号整型相加时,其结果可能是一个w+1位的无符号数 。
return1在c语言中是什么意思  1在c语言中是什么意思

文章插图
当两个w位的无符号整型相加时其和等于或超过时,就会发生溢出,其结果为和与的模运算:
return1在c语言中是什么意思  1在c语言中是什么意思

文章插图
补码加法存在正溢出与负溢出:
return1在c语言中是什么意思  1在c语言中是什么意思

文章插图
首先要明白,一个正数和一个负数相加,结果一定不会溢出(因为结果的绝对值一定小于两个加数的绝对值,两个加数都表达出来了,结果一定能表达出来 。)
所以,发生溢出的情况一定是符号相同的两个数相加 。
分情况讨论:
① 正整数pa + 正整数pb = r
符号位0,数位相加,如果结果的符号位变成1了,那一定是两个加数的更高位相加进上来的 。
假设将一个长度 w=4 的0、1 串映射到有符号整数,其更大的正数只能是0111,也就是7 。
0111+0001 = 1000 // 7 + 1 = 8-2^4 = -8,向下溢出
0111+0011 = 1010 // 7+ 3 = 10-2^4 = -6,向下溢出
发生向下溢出,判断的方式之一是:r<pa || r<pb 。
② 负整数na + 负整数nb = r
符号位都是1,所以符号位一定会进位 。数位相加,如果最后符号位是0,说明结果变成正的了,那一定是发生溢出了(负+负!=正) 。
假设将一个长度 w=4 的0、1 串映射到有符号整数,其最小的负数只能是1000,也就是-8 。
1000+1111 = 11000 ->0110 // -8+(-1) = -9+2^4 = 7,向上溢出
1011+1011 = 10110 ->0110 // -5+(-5) = -10+2^4 = 6,向上溢出
另外一种情况,没有改变符号位的溢出,属正常溢出,正如有符号位扩展、算术移位一样:
1100+1100 = 10000 ->0000 // -4+(-4)= -8,正常溢出
1111+1111 = 11110 ->1110 // -1+(-1)=-2,正常溢出
发生向上溢出,判断的方式之一是:r<pa || r<pb 。

return1在c语言中是什么意思  1在c语言中是什么意思

文章插图
CPU的标志寄存器有一个溢出标志位,反映有符号数加减运算是否溢出 。如果运算结果超过了8位或者16位有符号数的表示范围,则OF置1,否则置0 。
7 整数的乘除① 两整数乘除的结果还是一个整数类型(类型一致),如果是除法,可能存在舍入(舍入到零,向上舍入,向下舍入)的情况;
② 两整数乘法要考虑溢出的情况 。
③ 位运算也是一种特殊的整数乘除,乘数与除数是2的不同的整数幂(当一个整数乘除一个常数时,这个常数如果不是某个整数次幂,可以拆解成不同的幂次的加减) 。
8 代码示例8.1 带符号数产生意外结果的例子 。这个例子会造成无限循环,因为sizeof会返回unsigned int 类型,由此带来的结果是,i - sizeof(char)这个表达式的求值结果将会是 unsigned int (隐式转换 !!),i 会隐式转换为unsigned,i从 0 减 1 后变成-1,其二进制编码是 0xFFFFFFFF,转换成无符号数是2^32-1,从而产生无限循环,有时候你需要特别留心这种不经意的错误 !

推荐阅读