是否有可能“遍历”struct的内容?

时间:2014-11-01 21:47:10

标签: c loops struct typedef

我刚开始第一次使用typedef,而且我也没有使用过很多结构,尽管我很了解它们。

我创建了一个类型调用Max7219_t,如下所示:

typedef struct {
    uint16_t digit1,
    uint16_t digit2,
    uint16_t digit3,
    uint16_t digit4,
    uint16_t digit5,
    uint16_t digit6
    uint16_t digit7,
    uint16_t digit8,
    uint16_t intensity,
    uint16_t _shutdown,
    uint16_t scanl,
    uint16_t testmode,
    uint16_t decodetype } Max7219_t;

稍后在代码中,在我声明了此类型的变量并添加了值之后,我需要一次传输struct中的每个字节,理想情况是在for循环中。

除了直接引用每个成员(即*display->digit1,然后是*display->digit2等)之外,还有什么方法可以做到这一点吗?从本质上讲,是否有一种方法可以像使用数组一样枚举每个条目?

我不想只将整个事物转换为数组,因为我几乎肯定会在开发过程中为这个和其他结构添加不同的类型。

我觉得我在这里遗漏了一些明显的东西。我以为我可以只增加一个指针,但由于结构成员的大小不一样,我觉得这不会像指向数组一样工作。另外,在迭代for循环时,我不确定for(q = 0; q != sizeof(Max7219_t); q++)之类的东西是否也能正常工作。

非常感谢任何帮助!

5 个答案:

答案 0 :(得分:2)

如果您需要访问"隐藏"在struct之后,有几种方法:

  • 的memcpy()
  • for for type-casted pointer

最后一种方法似乎最接近你想要的,所以也许是这样的:

Max7219_t yourStructure;
// ...

const uint8_t* const pointer = (const uint8_t*)&yourStructure;
for (size_t i = 0; i < sizeof(yourStructure); ++i)
{
    uint8_t byte = pointer[i];
    ...
}

你的问题并不完全清楚......

答案 1 :(得分:1)

由于您的类型相同,因此请创建这些类型的数组:

typedef struct
{
     uint16_t mode[13] ;

}  Max7219_t ;

你通过任何其他数组迭代它。

 Max7219_t var = { 0 } ;

 for( size_t i = 0 ; i < 13 ; i++ )
 { 
     var.mode[i] = 12345 ;
 }

此方法不允许您使用元素的名称:digit1,digit2 ......

您可以使用枚举来获取这些枚举,这些枚举对应于数组中的正确元素。

enum
{
    digit1 = 0 ,
    digit2 = 1 ,
    digit3 = 2 ,
    //... and so on
} ;

答案 2 :(得分:1)

如果你想:

  

稍后在代码中,在我声明了这种类型的变量并添加了值之后,我需要一次一个地传输结构中的每个字节,理想情况是在for循环中。

您可以使用memcpy()复制原始数据,或者如果您想要逐字节访问<34> &#34;你可以:

char *ptr = (char*)&Max7219_t_instance;
for(int i = 0; i < sizeof(Max7219_t) ++i){
    // Work with bytes
}

请注意,您不能将任何内容更改为数组,您可以使用不同类型转换创建指针来处理相同的数据。

如果你想通过结构成员进行迭代(并且它们不是同一类型......否则使用2501s answer)你需要反思。有are ways how to employ reflection in C,但我会担心性能影响。

想象一下情况:

??? value = display->digit[x]; // This can be char/short/int/long...

您可以在左侧使用long解决此问题,但使用浮点数和字符串...

哦,好吧......您可以为MS编译器解析.pdb或者为gcc打开调试部分(启用-g),但它远离便携式C实现。

但是当您需要使用整数类型(或者您可以使用原始二进制数据)时,可以创建如下数组:

int Max7219_t_structure_members[] = {sizeof(uint16_t), sizeof(uint16_t) ..., 0 };

每个结构成员的大小和

sum(Max7219_t_structure_members) == sizeof(Max7219_t)

为了论证,让我们想象你需要使用最大sizeof(long)字节大的类型。

int offset = 0;
for(int i; Max7219_t_structure_members[i]; ++i){
    long tmp = 0;
    // This line will work only on little-endian machines
    memcpy(&tmp, ((char*)insntance)+offset, Max7219_t_structure_members[i])

    // Do your work

    offset += Max7219_t_structure_members[i];
}

但是你必须手动维护结构。我不知道任何可以帮助您使用自动版本的宏(至少在gcc中)。

答案 3 :(得分:0)

由于结构中的所有元素都是相同的大小,理论上你可以声明一个指向uint16_t的指针,指向结构中的第一个元素,如下所示:

Max7219_t my_structure;
uint16_t *p = (uint16_t *)&my_structure;
for (int i = 0; i < ELEMENTS_IN_STRUCTURE; i++, p++) {
    *p = some_value;
}

但是,我不建议这样做,因为如果你在结构中添加了一些其他变量类型它就行不通,它完全违背了结构和类型的目的。

我要做的是编写一个根据需要填充值的函数。

void init_max_77219(Max7219_t *my_structure) {
    my_strcture->digit1 = ...;
}

然后只要你需要初始化结构就调用它。

对于这个特殊场景(结构充当uint16_t的包),如果需要,可以坚持使用数组,然后在其他地方存储不同类型的变量。

答案 4 :(得分:-1)

工会的用例:

union variable {
    Max7219_t yourStructure;
    uint16_t array[13];
);