迭代c中的结构

时间:2017-11-20 16:31:58

标签: c pointers struct boolean

我正在编写一个与此代码类似的单元测试,我正在尝试在设置它们时测试我的值,以便我知道发生了什么。当我运行以下代码时,我不明白为什么ptr值没有设置为1。相反,当我运行它时,它给我一个10,64,0,0的输出。

非常感谢任何解释或建议!

#include <stdio.h>
#include <stdbool.h>

typedef struct
{
    bool bOne;
    bool bTwo;
    bool bThree;
    bool bFour;
} items;

int main()
{
    items item;
    item.bOne = 0;
    bool *ptr = &(item.bOne);

    for(int i = 0; i < sizeof(items)/sizeof(bool); i++)
    {
        *ptr = 1;
        *ptr++;
        printf("ptr value = %d\n", *ptr);
    }
    return 0;
}

2 个答案:

答案 0 :(得分:2)

*ptr++中,++的优先级高于*,因此此后增加指针,并读取并丢弃最初指向的值。现在指针已经递增,您正在printf中读取未初始化的内存。如果您打算增加指向的值,请尝试:

(*ptr)++;

或者

ptr[0]++;

修改

嗯,因为你的循环绑定是基于结构大小的bool的数量,你的意图可能是增加指针。在这种情况下,您不需要同时取消引用它,并且您不应期望在printf中获得任何有意义的内容。另外,正如所指出的那样,由于struct不是一个数组,因为编译器可能决定添加填充,你将徘徊在未定义的行为域中:

来自C99§6.7.2.1:

  

12结构或联合对象的每个非位字段成员都以适合其类型的实现定义方式对齐。

     

13在结构对象中,非位字段成员和位域所在的单元具有按声明顺序增加的地址。指向适当转换的结构对象的指针指向其初始成员(或者如果该成员是位字段,则指向它所在的单元),反之亦然。在结构对象中可能有未命名的填充,但不是在它的开头。

答案 1 :(得分:1)

你有两个主要问题。

首先,您有一个逻辑错误,即在打印出指向的值之前推进指针;而不是打印您刚刚设置的东西的值,您将打印下一个未初始化成员的值。您需要反转advance和print语句的顺序,如下所示:

conda install packageName

或者只是将操作合并到一个表达式中:

printf("ptr value = %d\n", *ptr);
ptr++; // note no * operator

这假设您可以使用printf("ptr value = %d\n", *ptr++); 来打印%d值 - 我不确定这种情况(可能必须明确地将参数强制转换为bool)。

但是你有一个更大的问题 - 它不能保证你可以用这样的指针迭代(int)类型的成员。即使所有成员都是相同的类型,也不能保证成员之间不会填充(这取决于struct类型的大小和平台的对齐要求) 。

您的代码可能按预期工作,或者可能导致bool实例中的数据损坏或任何其他问题。更安全的做法是使用指向这些成员的单独指针数组,因为 保证您可以使用指针迭代数组:

struct

如果您仍想要输出,请编写

bool *members[] = { &item.bOne, &item.bTwo, &item.bThree, &item.bFour, NULL };

bool *ptr = members[0];
while ( ptr )
{
  *ptr++ = 1;
}

您可以获得创意,并在print语句中组合赋值和指针前进:

*ptr = 1;
printf( "ptr value = %d\n", *ptr++ );

但这可能会让你受到打击。