我是C的初学者。
此代码执行SCHAR_MIN
执行的操作:
#include<stdio.h>
int main(void)
{
printf("Minimum Signed Char %dn",-(char)((unsigned char) ~0 >> 1) - 1);
return 0;
}
这是我的理解:(unsigned char)
采用无符号字符的位,即"0000 0000"。~0
给出它的补码,即"1111 1111",>> 1
将"1111 1111"左侧的"1"变为0,因此它将给出"0111 1111"。将"0111 1111"转换为整数将得到 127,这是最大有符号字符。为了得到最小值,我们需要反转 127,所以我们将其乘以-
得到 -127,- 1
得到 -128,这是最小值。告诉我我是否误解了什么。
问题:
(char)
在这里的作用是什么?就在((unsigned char) ~0 >> 1)
之前?它代表什么?
- 常量
0
的类型是int
,因此~0
会产生一个int
值,例如 0xFFFFFFFF(假设为 32 位)。这实际上是一个负值,对应于 2 补码中的十进制-1
。 - 如果我们只对最低有效字节感兴趣,我们可以通过转换为
unsigned char
来屏蔽该字节,最终得到0xFF
。这样,我们暂时也放弃了签名格式。 - 然后
>>
运算符隐式地将我们的临时unsigned char
操作数提升回int
,但由于值0xFF
(255
)适合int
,这就是我们得到的值。我们最终对有符号类型进行了位移,但具有正值。 0xFF >> 1
给出0x7F
= 127。实际上,整个((unsigned char) ~0 >> 1)
只是键入127
的一种复杂方式。因为在所有具有 8 位字节的普通系统上,这就是我们得到的。- 现在,这被显式转换为带有强制转换的
char
。它仍然是相同的值 127。 -
给-127
.一元-
运算符隐式将结果提升回int
。-127 - 1 = -128
.
请注意,char
的符号性是实现定义的。它也可能是未签名的,在这种情况下,演员阵容没有多大意义。无论如何,-
的隐性提拔给了我们一个签约int
,所以演员阵容char
一无所获。
有关整数升级的详细信息,请参阅隐式类型升级规则。
此代码可能作为适用于所有有符号整数类型的模式出现,因为强制转换对于int
和更广泛的类型是必需的,尽管在普通 C 实现中char
不需要它。
考虑-(Type)((unsignedType) ~0 >> 1) - 1)
.通过<code>(<i>Type</i>)</code>
转换,我们得到了所需的阴性结果。没有它,我们会得到一个错误的正结果:当Type
int
,并且使用二的补码时,((unsigned <i>Type</i>) ~0 >> 1
是一个高位关闭而其他位打开的unsigned int
。对此应用一元-
会产生unsigned int
,减法也是如此。因此,结果将是正值,而不是所需的负值。使用强制转换(Type)
,该值在一元-
之前转换为有符号类型,因此产生负值。
因此,此代码可能是通过对所有有符号整数类型使用模式-(Type)((unsignedType) ~0 >> 1) - 1)
而产生的。尽管在普通 C 实现中不需要转换char
或short
,但它仍然存在,因为在模式中编写代码时进行了简单的替换。
这也解释了为什么演员阵容要char
而不是signed char
:它是简单地用long long int
、long int
、int
、short
和char
代替Type
,忽略了char
与signed char
的特殊待遇。(这在char
比int
窄的普通C实现中不是问题,但是使用signed char
可以使代码在char
宽度与int
相同的奇异C实现中工作。
检查您在其中找到此内容limits.h
文件可能会显示其他类型的相同模式。