c - 为什么一位 `int` 位域的值是 0 和 −1?

标签 c

为什么这段代码会产生所示的输出?

    #include<stdio.h>
    struct sample{
        int x:1;
    }a[5]={0,1,2,3,4};
    int main(){
        int i;
        for(i=0;i<5;++i){
            printf("%d ",a[i].x);
        }
        return 0;
    }

使用 OnlineGDB 编译和执行时的输出是:

0 -1 0 -1 0 

最佳答案

int x:1 充当有符号的一位整数。根据 C 2018 6.7.2 5,实现可能会将声明为 int 的位字段视为 unsigned int,但您使用的 C 实现似乎将其视为已签名。

此外,C 实现使用二进制补码。在二进制补码中,一个 n 位整数有 1 个符号位和 n−1 个值位。由于您的整数是一位,因此它有一个符号位和零值位。根据二进制补码规范 (C 2018 6.2.6.2 2),符号位的值为 −2M,其中 M 是值位数。因为它是零,所以符号位的值为 −20 = −1。

因此,当位为零时,位域的值为 0,当位为 1 时,位域的值为 -1。1

在使用 ={0,1,2,3,4}; 进行初始化期间,数组中的第一个位字段设置为零。但是,其他溢出位域中可表示的值。根据 C 2018 6.3.1.3 3,生成实现定义的结果或引发实现定义的信号。此 C 实现似乎正在生成源值的低位作为位域中位的值。这会在五个位字段中产生位 0、1、0、1 和 0,分别表示值 0、-1、0、-1 和 0。因此,当它们被打印时,值 0、-1、 0、-1 和 0 结果。

脚注

1 这可能被视为二进制补码正常工作方式的自然结果:对于八位,范围是 −128…127。对于四位,范围是 −16…15。比特越来越少,范围是-8…7、-4…3、-2…1,最后是-1…0。

关于c - 为什么一位 `int` 位域的值是 0 和 −1?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60489275/

相关文章:

c - 如何知道 C 语言中是否存在文件?

objective-c - 逻辑 && 语句

java - 给定一个二叉树,其中每个节点都有一定的权重。您必须返回二叉树中的最大权重

c - 从一个字符中读取单个位

c - 如何用 C 编写输入整数文件结尾的代码

被跳过的字符是输出文件 i/o

c - b = false 与 if (b) b = false

c - 为什么在 C 语言的 Ubuntu Linux 上 pango_layout_get_pixel_size 略有错误

python - 使用共享内存从单独的 C 进程访问 numpy 数组

c - 整数的“字符数组”到 'Integer array'