C 带符号字符的位运算
我发现了一个程序,可以打印有符号字符的最大值和最小值。虽然我们在课堂上学习了位运算,但我不明白什么时候所有的运算符都放在一起了C 带符号字符的位运算,c,bit-manipulation,C,Bit Manipulation,我发现了一个程序,可以打印有符号字符的最大值和最小值。虽然我们在课堂上学习了位运算,但我不明白什么时候所有的运算符都放在一起了 int main(void) { printf("Minimum Signed Char %d\n",-(char)((unsigned char) ~0 >> 1) - 1); printf("Maximum Signed Char %d\n",(char) ((unsigned char) ~0 >>
int main(void)
{
printf("Minimum Signed Char %d\n",-(char)((unsigned char) ~0 >> 1) - 1);
printf("Maximum Signed Char %d\n",(char) ((unsigned char) ~0 >> 1));
}
例如,我知道~翻转位并>>将其向右移动。因此,我相信~0>>1,翻转所有位并将其向右移动一个位置。但是为什么我们要减去1,我认为2的补码加1呢 用于计算最小值的表达式前面有一个
-
运算符:
-(char)((unsigned char) ~0 >> 1) - 1
因此,表达式中操作数求值的顺序为:
~0>>1
并将结果强制转换为无符号字符
char
-
运算符和更改上一个结果的符号-1
)以获得最小可能值(0
值被视为正值)
具有所有位1(最大正(无符号字符)~0
)无符号字符
关闭用于符号的最高位(最大正数>1
)有符号字符
将该值作为-(char)
求反(注意:应为char
)带符号的char
用于现在的负值,因为在二的补码中,最负的值的大小比最正的值大一个(因为零的值具有符号位,并且二的补码中没有“负零”)-1
这就是为什么011111=127,但1000000=-128 首先取最大值,在原始表达式中添加括号以澄清运算顺序,原始表达式变为
(char) (((unsigned char) (~0)) >> 1)
首先,~0
生成类型为int
的值(因为常量0
具有该类型),其位模式由所有1
组成(不包括任何填充位)。这将是一个负数,因为它的符号位将被设置
强制转换将该值转换为类型无符号字符
,这将导致该类型的值具有所有位1
但是类型有符号字符
的值位正好比无符号字符
少一个,因为它的表示与无符号字符
的表示大小相同,没有任何填充位,有符号字符
使用它的一个位作为符号位。将右移一个位置会使附加值位偏移,从而产生一个无符号字符
,其值是类型有符号字符
可以容纳的最大值
然后将结果转换为类型char
,这是毫无意义的。转换后该值将保持不变,但
char
与signed char
是不同的类型,前者不一定是有符号类型,因此强制转换到char
无论如何都不能用于与signed char
的值范围相关的任何用途printf()
之前,它将(进一步)转换为类型int
有符号字符的最大值
最小值的表达式只比最大值的倒数少一个。这是正确的最小值,前提是有符号字符
以二的补码形式表示。虽然我所知道的每个现代实现确实使用2的补码形式表示有符号整数,但C明确允许使用另外两种形式,这两种形式的最小值都等于其最大值的倒数。该程序将在平台上生成错误的最小值,该平台具有带符号字符
的表示形式,这是“未定义的实现行为”,即它依赖于实现定义的行为,但实现可能会定义它是未定义的行为。如果您的目标是打印字符的最大值和最小值
,请执行#包括
并打印出字符最小值
,并且不考虑字符最大值
为零positive@M.M在他的例子中是!!!我的答案是正确的,关于为什么在他的例子中它们不能相互补充。