代码之家  ›  专栏  ›  技术社区  ›  Akay

循环遍历C中结构中的元素以提取单个元素的值和数据类型

  •  2
  • Akay  · 技术社区  · 7 年前

    我有一个要求,我在C语言中有一个大的结构,由大约30多个不同数据类型的不同元素组成:

    typedef struct {
      type1 element1;
      type2 element2;
      type3 element3;
      type2 element4[10];
      ...
      typeN elementN;
    } my_messg_struct;
    

    其中,这基本上是通过串行协议发送的消息中的一组元素。此消息具有在上述结构中捕获的不同数据类型的各种元素。同样,我也有很多其他的信息。现在我必须编写一个泛型函数,它负责读取这些消息结构,并遍历每个元素,读取元素的值和数据类型,然后通过串行端口进行传输。我需要先读取数据类型,因为在我的情况下,不同数据类型的传输顺序是不同的。

    所以,基本上,我只是想知道如何在C中循环遍历结构元素,以便能够读取结构中每个元素的值和数据类型?

    2 回复  |  直到 7 年前
        1
  •  3
  •   pbn    7 年前

    你可以试着用 X macros ,但生成的源代码可读性值得怀疑:

     #include <stdio.h>
    
     #define LIST_OF_VARIABLES \
         XI(int, value1) \
         XD(double, value2) \
         XU(unsigned, value3)
    
    
     #define XI(int, name) int name;
     #define XD(double, name) double name;
     #define XU(unsigned, name) unsigned name;
     typedef struct A {
         LIST_OF_VARIABLES
     } A;
     #undef XI
     #undef XD
     #undef XU
    
     void print_variables(struct A a)
     {
     #define XI(type, name) printf("%s = %d\n", #type, a.name);
     #define XD(type, name) printf("%s = %f\n", #type, a.name);
     #define XU(type, name) printf("%s = %u\n", #type, a.name);
     LIST_OF_VARIABLES
     #undef XI
     #undef XD
     #undef XU
     }
    
     int main(void) {
         A a = {
             .value1 = 10,
             .value2 = 0.5,
             .value3 = 1,
         };
         print_variables(a);
         return 0;
     }
    

    现在在每个 #type

        2
  •  1
  •   Eliyahu Machluf    7 年前

    C不支持在struct成员上移动(类似于C#,Java中的反射)。您需要用一个结构来包装每个元素,说明其大小、类型和数据。像这样的:

    typedef enum {
        et_int,
        et_long,
        et_string,
        et_array
    }element_type_t;
    
    struct element {
        element_type_t type;
        int element_length;
        void *data;
    };
    

    顺便说一下,如果使用google协议缓冲区,有一种方法可以获得struct的反射。(见 https://en.wikipedia.org/wiki/Protocol_Buffers )这样,您就可以要求每个结构具有哪些成员以及属于哪种类型。但是,使用它需要使用协议缓冲编译器并将协议缓冲文件添加到项目中。