c标准是否保证有符号和无符号的位模式解释?

时间:2011-10-27 13:55:41

标签: c bit standards signed representation

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 */

4 个答案:

答案 0 :(得分:2)

对于未签名,是的。对于签名类型,不;该标准允许2的补码,1的补码或符号幅度表示。标准(C99)的相关部分是6.2.6.2。

另一个问题是unsigned u = (int)0xffffffff之类的代码会调用未定义的行为,因为这会导致整数溢出(第6.3.1.3节)。

另一个问题是char c = 0xff; c >> 4之类的代码是实现定义的,原因有两个。首先,char可以是signedunsigned。其次,如果它是signed,则右移一个负数是实现定义的(第6.5.7节)。

答案 1 :(得分:2)

我将做出一个额外的假设,即在讨论的实现中没有类型具有填充位。我们一次拿一个:

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 */

是。 iintunsigned的推广具有确定性,在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可表示的值范围内时才需要这样做。

char c = 0xff;
if (c >> 4 == 0xf) /* do something */

char可能已签名或未签名。如果它是未签名的,则测试将为真;如果签名,则cc >> 4将具有实现定义的值,因此可能不是真的。

signed char c = 0xff;
if (((c >> 4) & 0xff) == 0xf) /* do something */

c将具有实现定义的值,因此测试可能不正确。

请注意,除memcpy()之外的所有问题仅与有关,而不是表示

答案 2 :(得分:1)

无符号数保证模2 ^ n算术。对签名的人没有这样的保证。

没有关于位模式的说法。请注意,0xfffffff不是“位模式”,它是一个数字(其“位模式”对C ++标准没有意义),如果x是32位无符号,则保证满足x + 1 = 0你指定0xffffffff的号码。

答案 3 :(得分:0)

要记住的关键项是十六进制文字(例如0x0F)引用(此处为:15),而不是存储位和字节的顺序物理。

它是如何存储的 - 取决于机器 - 有些将首先存储最低有效位,有些首先存储高位,而在x86上存储AFAIK它是最不重要的字节,但高位< / em>首先。

但总是如此,0x000F等于15