[英]Does c standard guarantee bit pattern interpretation for signed and unsigned?
C标准是否规定应如何解释位表示? 换句话说,如果条件始终为真,则执行以下操作吗? 假设sizeof(int)= 4且CHAR_BIT = 8
unsigned u = 0xffffffff;
if (u == 4294967295) /* do something */
int i = 0xffffffff;
if (i == -1) /* do something */
unsigned u = (int)0xffffffff;
if (u == 0xffffffff) /* do something */
int i = hex_literal;
unsigned u;
memcpy (&u, &i, sizeof (u));
if (i == u) /* do something */
if ((i & 0x7fffffff) == (u & 0x7fffffff)) /* do something */
int i = hex_literal;
unsigned u = i;
if (i == u) /* do something */
unsigned u = hex_literal;
int i = u;
if (i == u) /* do something */
int i = hex_literal;
unsigned u = hex_literal;
if (i == hex_literal && u == hex_literal) /* do something */
char c = 0xff;
if (c >> 4 == 0xf) /* do something */
signed char c = 0xff;
if (((c >> 4) & 0xff) == 0xf) /* do something */
对于未签名,是的。 对于带符号的类型,否; 该标准允许2的补码,1的补码或符号幅度表示。 标准(C99)的相关部分是6.2.6.2。
一个单独的问题是,诸如unsigned u = (int)0xffffffff
调用未定义的行为,因为这会导致整数溢出(第6.3.1.3节)。
另一个问题是该代码,例如char c = 0xff; c >> 4
char c = 0xff; c >> 4
是实现定义的,这有两个原因。 首先, char
可以是有signed
也可以是unsigned
。 其次,如果它是带signed
,则右移负数是实现定义的(第6.5.7节)。
我将做出额外的假设,即所讨论的实现中没有类型具有填充位。 让我们一次带他们一个:
unsigned u = 0xffffffff;
if (u == 4294967295) /* do something */
是。
int i = 0xffffffff;
if (i == -1) /* do something */
否。将超出范围的数字转换为带符号的类型将给出实现定义的结果。
unsigned u = (int)0xffffffff;
if (u == 0xffffffff) /* do something */
不,与前面的示例相同。
int i = hex_literal;
unsigned u;
memcpy (&u, &i, sizeof (u));
if (i == u) /* do something */
if ((i & 0x7fffffff) == (u & 0x7fffffff)) /* do something */
是。 该标准保证有符号类型中的每个值位在对应的无符号类型的对象表示中具有相同的值。
int i = hex_literal;
unsigned u = i;
if (i == u) /* do something */
是。 i
从int
到unsigned
的提升是确定性的,并且在对u
的赋值和比较中都产生相同的值。
unsigned u = hex_literal;
int i = u;
if (i == u) /* do something */
是的,但是仅当hex_literal
处于可以由int
表示的(正)值范围内时,否则实现定义的结果将再次出现。
int i = hex_literal;
unsigned u = hex_literal;
if (i == hex_literal && u == hex_literal) /* do something */
u == hex_literal
将始终评估为true,但是i == hex_literal
仅在hex_literal
处于int
表示的值范围内i == hex_literal
需要这样做。
char c = 0xff;
if (c >> 4 == 0xf) /* do something */
char
可以是已签名或未签名。 如果未签名,则测试为true;否则为true。 如果已签名,则c
和c >> 4
将具有实现定义的值,因此可能不正确。
signed char c = 0xff;
if (((c >> 4) & 0xff) == 0xf) /* do something */
c
将具有实现定义的值,因此测试可能不正确。
请注意,除了memcpy()
以外,您所有的问题仅与值有关,而与表示有关 。
无符号数保证了模2 ^ n的模运算。 签名者没有这样的保证。
关于位模式,什么也没说。 请注意,0xfffffff不是“位模式”,它是一个数字(其“位模式”对于C ++标准没有意义),如果x
是您要使用的32位无符号数,则保证满足x + 1 = 0分配为0xffffffff。
要记住的关键项是十六进制文字(例如0x0F
)是指值 (此处为15
),而不是物理上存储位和字节的顺序。
它是依赖于机器这是怎么保存-有些人会首先存储最低显著位,其他高位第一次,据我所知在x86它至少显著字节第一,但高位第一。
但始终是真的, 0x000F
等于15
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.