【问题标题】:Struct variable doesn't changed by assignment结构变量不会因赋值而改变
【发布时间】:2017-04-17 13:47:40
【问题描述】:
struct st  
{  
    int a1 : 3;  
    int a2 : 2;  
    int a3 : 1;  
}

void main(void)
{
    x.a3 = -1;  

    if (x.a3 == -1) printf("TRUE\n");
    else printf("FALSE\n");

    x.a3 = 1;  
    if (x.a3 == 1) printf("TRUE\n");
    else printf("FALSE\n");  
}

万一,'x.a3 = -1;'首先如果是TRUE
但是,为什么 'x.a3 = 1' 在第二个 if 没有改变?它仍然是 x.a3 = -1。


如果我先输入 'x.a3 = 1;' ,它仍然是 x.a3 = = 1 !没变!

Debug Result in XCode

【问题讨论】:

  • void main() 是无效签名。最小签名是int main(void)x 是什么?代码无法编译。提供minimal reproducible example
  • @Olaf 当我阅读 C11 5.1.2.2.1 2 时,“它应该使用 int 的返回类型来定义......或以其他一些实现定义的方式。” void main(void) 如果有效,则由实现定义,不一定无效。我想这取决于“或”。 IAC,当然不是 OP 的关键问题。
  • @chux:这有待解释。除此之外,所有全尺寸操作系统都需要int 结果。

标签: c struct signed bit-fields twos-complement


【解决方案1】:

问题是,一个有符号的1 位变量只能保存两个值,-10(阅读Two's complement)。保持1 的值是不够的(确切地说是+1)。

详细说明,同时写作业

 x.a3 = 1;

整数常量1的值存储在为成员a3保留的内存位置,但在访问变量时,根据变量的符号(可能是signedunsigned,实现定义行为,根据章节 §6.7.2/P5),表示将从内存中读取。

存储1 在二进制补码中的表示,将产生结果 -1(根据 MSB 值),因此使用 == 1 的条件检查将始终失败.

【讨论】:

  • 实现定义了位域中的普通int 是有符号值还是无符号值。事实上,几乎所有关于位域的内容都是由实现定义的。
  • @chux 感谢您的纠正,我以某种方式错过了之前的评论。已更新。
【解决方案2】:

因为字段a3 是一个1 位的int(因此是有符号的),它只能保存一个值0(如果该位为0)或-1(如果该位是符号位,是 1)。因此,当您尝试分配值 1 时,会存储该值的表示形式,并且给定数据类型中的表示形式为 -1。

仅仅因为 1 位 int 中的值 -1 与 1 位 unsigned int 中的值 1 具有相同的表示形式,并不意味着它们与同一事物进行比较。

【讨论】:

    【解决方案3】:
    int a3 : 1;  
    

    是一个带有位字段的结构,它定义了用于存储 var 的空间。您正在使 a1 成为一位有符号的 int,它只能保存值 -1 和 0。如果您打算让 a3 保存值 1,那么您可能想要的语法是 int a3 = 1,然后是多种方式之一这样做可能看起来像这样

    struct st  
    {  
        int a1 : 3;  
        int a2 : 2;  
        int a3 : 1;  
    };
    
    
    void main(void)
    {
        struct st x = {1,2,3};
        x.a3 = -1;  
    
        if (x.a3 == -1) printf("TRUE\n");
        else printf("FALSE\n");
    
        x.a3 = 1;  
        if (x.a3 == 1) printf("TRUE\n");
        else printf("FALSE\n");  
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-12-18
      • 1970-01-01
      • 2021-05-11
      • 1970-01-01
      • 1970-01-01
      • 2017-03-20
      相关资源
      最近更新 更多