在C语言中设置的位,它没有给我正确的输出?

问题描述 投票:1回答:1

我的结构体块我想保留一个位。

struct bitset {
    int number: 1;
};
typedef struct bitset bit;

但代码总是给我46或47的输出。我不明白。

int main() {
    bit x;
    x.number = 1;
    printf("%d", x);
    return 0;
}
c struct bit
1个回答
2
投票

这段代码由于使用了一个不正确的格式指定符而导致了未定义的行为。这段代码由于使用了错误的格式指定符而导致了未定义的行为。%d 格式指定器必须与类型为 int但你通过值传递一个结构来代替。

作为未定义的行为,标准对程序的行为没有任何要求,所以你不应该期望任何特定的输出或行为。

另外,有可能位域是有符号的,因此只能存储 0-1 反正。使用 unsigned int number: 1 以保证能够存储 1.


1
投票

C-99 6.7.2.1 结构和联合说明#10(强调是我的)。

实现可以分配任何足够大的可寻址存储单元,以容纳一个位域。如果有足够的空间,紧跟在结构中另一个位字段后面的位字段应被装入同一单元的相邻位。如果剩余空间不足,则不适合的位字段是放到下一个单元中,还是与相邻的单元重叠,由实施定义。一个单元内的位字段的分配顺序(高阶到低阶或低阶到高阶)由实施定义。可寻址存储单元的排列方式未作规定。

强调是我的。 唯一合理的访问字段的方式是用 x.number. 把它作为参数传递给你的 printf 调用,应该可以正常工作(不过,请看我下面最后的补充)。


所以,这一切说明的是,结构体的对齐方式可能和位字段的对齐方式不一样。 整个结构甚至不需要是sizeof(int),但你可以以该字段声明的类型访问任何位字段。


正如@M.M所指出的,一个有符号的单位字段将被解释为负值。 根据 C-99 6.7.2.1 结构和联合指定器#8:

...此外,一个成员可以被声明为由指定数量的位组成(包括符号位,如果有的话)... ...

所以,虽然你可以将1存储在 x.number (有符号或无符号),当你把它作为一个整数读出来的时候,它将被解释为-1,这是因为 延长标志. 对于单位字段,如果你的编译器允许的话,几乎总是最好使用无符号位字段(目前大多数都支持)。 你总是可以使用位掩码来检查相关的位(假定 二重奏),但那会变得很丑陋,而且有点违背了使用单比特字段的目的。

对于多比特字段,你是使用有符号还是无符号,取决于你使用它们的目的。 如果你将它们用于数字,那么数字范围决定了你是要有符号还是无符号。 如果您将它们作为一个位标志数组来处理,这其实并不重要,因为无论如何您都会应用位掩码来解释它们,但如果它们是无符号的,那么对于诊断读数来说还是比较容易的(当未使用的最有意义的位都是零时,认知负荷较低)。

© www.soinside.com 2019 - 2024. All rights reserved.