位域操作-设置位

发布于 2024-12-04 06:37:30 字数 438 浏览 1 评论 0原文

#include<stdio.h>

int main()
{
    struct s{
      int bit_fld:3;
    };
    s a;
    a.bit_fld=0x10;
    a.bit_fld =( a.bit_fld | (1<<2));
    printf("%x\n",a.bit_fld);
    return 0;
}

该程序输出fffffffc

我尝试手动计算输出,但无法获得编译器产生的输出。

bit_fld = 00010000 和 (1<<2) = 0100 两者相或将得到 00010100,即十六进制的 0x14。 为什么我对输出的看法是错误的?帮助我理解我错在哪里。

#include<stdio.h>

int main()
{
    struct s{
      int bit_fld:3;
    };
    s a;
    a.bit_fld=0x10;
    a.bit_fld =( a.bit_fld | (1<<2));
    printf("%x\n",a.bit_fld);
    return 0;
}

This program outputs fffffffc.

I tried to do manual calculation of the output and I could not get the output that the compiler produced.

bit_fld = 00010000 and (1<<2) = 0100 oring both wil result in 00010100 which is 0x14 in hexadecimal.
Why my perception of the output is wrong ? Help me to understand where I'm mistaken.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

空城旧梦 2024-12-11 06:37:30

a.bit_fld只有3位大,它不能存储值0x10。行为是实现定义的,但在本例中它可能存储了 0。

然后 1 <<正如你所说,2 是二进制 100 。假设我们在第一步确实存储了 0,则 ( a.bit_fld | (1<<2)) 的结果是一个值为 4 的 int (二进制 100)。

在有符号 2 的补码 3 位表示中,此位模式表示值 -4,因此如果将值 4 存储到 a.bit_fld 时得到 -4,则一点也不奇怪,尽管这又是实现定义的。

printf 中,a.bit_fld 在作为可变参数传递之前被提升为 int。 -4 的 2 的补码 32 位表示是 0xffffffffc,这就是您所看到的。

对于 %x 格式,将 int 而不是 unsigned int 传递给 printf 也是未定义的行为。不过,它似乎有效并不奇怪:对于一般的可变参数,在某些情况下传递 int 并将其读取为 unsigned int 是有效的。 printf 不是其中之一,但实现不会不遗余力地阻止它看起来正常工作。

a.bit_fld is only 3 bits big, it can't store the value 0x10. Behavior is implementation-defined, but in this case it has probably stored 0.

Then 1 << 2 is binary 100 as you say. Assuming we did store 0 at the first step, the result of ( a.bit_fld | (1<<2)) is an int with value 4 (binary 100).

In a signed 2's complement 3-bit representation, this bit pattern represents the value -4, so it's not at all surprising if -4 is what you get when you store the value 4 to a.bit_fld, although again this is implementation-defined.

In the printf, a.bit_fld is promoted to int before passing it as a vararg. The 2's complement 32 bit representation of -4 is 0xfffffffc, which is what you see.

It's also undefined behavior to pass an int instead of an unsigned int to printf for the %x format. It's not surprising that it appears to work, though: for varargs in general there are certain circumstances where it's valid to pass an int and read it as an unsigned int. printf isn't one of them, but an implementation isn't going to go out of its way to stop it appearing to work.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文