Her*_*mit 8 c casting type-conversion
我\xe2\x80\x99见过低级按位表达式,用于~0
生成所有s的位模式1
,然后将其用作掩码等。例如在K&R第45页上:
/* getbits: get n bits from position p */\nunsigned getbits(unsigned x, int p, int n)\n{\n return (x >> (p+1-n)) & ~(~0 << n);\n}\n
Run Code Online (Sandbox Code Playgroud)\n在我的机器上,(unsigned long) ~0
计算结果为0x FF FF FF FF FF FF FF FF
. 这让我们可以轻松生成1
大于int
s 的蒙版,这很好。
但是,\xe2\x80\x99t 应该(unsigned long) ~0
评估为 吗0x 00 00 00 00 FF FF FF FF
?没有任何后缀,0
被视为整数常量,因此~0
计算结果为0x FF FF FF FF
. 为什么 \xe2\x80\x99 不将其转换unsigned long
为零填充值?我在这里缺少什么?
编辑:在我的机器上,sizeof(int)
和sizeof(long)
分别是 4 和 8。
438*_*427 14
您的系统上~0
有一个int
位模式FF FF FF FF
,表示十进制值 -1。
当转换为时,unsigned long
您将一种整数类型转换为另一种整数。其规则可以在 C(草案)标准 n1570 的 6.3.1.3 中找到:
1 当一个整数类型的值转换为_Bool以外的其他整数类型时,如果该值可以用新类型表示,则该值不变。
2 否则,如果新类型是无符号的,则通过在新类型可以表示的最大值上重复加或减 1 来转换该值,直到该值在新类型的范围内。60)
60) 规则描述了数学值的算术,而不是给定类型表达式的值。
第一条规则不适用,因为 -1 不能在 中表示unsigned long
。应用第二条规则,即找到新值,如下所示
new-value = original-value + (ULONG_MAX + 1)
Run Code Online (Sandbox Code Playgroud)
在你的情况下:
new-value = -1 + (ULONG_MAX + 1) = ULONG_MAX
Run Code Online (Sandbox Code Playgroud)
所以新值是在您的系统上ULONG_MAX
具有代表性的值FF FF FF FF FF FF FF FF
。