[英]iterating through a struct in c
我正在编写一个与此代码类似的单元测试,我正在尝试在设置它时测试我的值,以便我知道发生了什么。 当我运行以下代码时,我不明白为什么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;
}
在*ptr++
, ++
优先级高于*
,因此这会使指针递增,并读取并丢弃最初指向的值。 现在指针已经递增,您正在读取printf
未初始化的内存。 如果您打算增加指向的值,请尝试:
(*ptr)++;
要么
ptr[0]++;
编辑
嗯,因为你的循环边界是基于适合结构大小的bool
的数量,也许你的目的是增加指针。 在这种情况下,您不需要同时取消引用它,并且您不应期望在printf
获得任何有意义的内容。 另外,正如所指出的,由于结构不是数组,因此编译器可能决定添加填充,因此您将徘徊于未定义的行为域:
从C99§6.7.2.1:
12结构或联合对象的每个非位字段成员都以适合其类型的实现定义方式对齐。
13在结构对象中,非位字段成员和位域所在的单元具有按声明顺序增加的地址。 指向适当转换的结构对象的指针指向其初始成员(或者如果该成员是位字段,则指向它所在的单元),反之亦然。 结构对象中可能存在未命名的填充,但不是在其开头。
你有两个主要问题。
首先,您有一个逻辑错误,即在打印出指向的值之前推进指针; 而不是打印您刚刚设置的东西的值,您将打印下一个未初始化成员的值。 您需要颠倒advance和print语句的顺序,如下所示:
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;
}
如果你还想要输出,那你就写
*ptr = 1;
printf( "ptr value = %d\n", *ptr++ );
您可以获得创意,并在print语句中组合赋值和指针前进:
printf( "ptr value = %d\n", (*ptr++ = 1) );
但这可能会让你受到打击。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.