在另一个结构中初始化和使用结构成员

时间:2019-06-19 20:59:26

标签: c struct initialization

我需要在新的struct(struct2)中使用先前声明的struct(struct1)。 我也想对其进行初始化,并使用struct1的某些成员来初始化struct2的其他成员。

具体地说,我想为struct1设置值并使用其中一些值来定义struct2其他成员的大小

我尝试了代码中显示的内容,但是我不明白为什么它不起作用。

typedef struct ytxModule{
    uint8_t nEncoders;
    uint8_t nDigital;
    uint8_t nAnalog;
    uint8_t nLedsPerControl;
};

typedef struct{
    ytxModule components = {4, 0, 0, 16};

    // encoder pin connections to MCP23S17
    uint8_t encPins[components.nEncoders][2] = {
      {1, 0},  
      {4, 3},   
      {14, 15},  
      {11, 12}   
    };
    // buttons on each encoder
    uint8_t encSwitchPins[components.nEncoders] = { 2, 5, 13, 10 }; 

}ytxE41Module;

我收到的错误消息是:

sketch\headers/modules.h:52:37: error: invalid use of non-static data member '<anonymous struct>::components'

  ytxModule components = {4, 0, 0, 16};

                                     ^

sketch\headers/modules.h:55:18: error: from this location

  uint8_t encPins[components.nEncoders][2] = {

任何帮助将不胜感激:)

2 个答案:

答案 0 :(得分:2)

最少的必要更改

您不能将typedef与初始值设定项混合使用-至少在C语言中不能混合使用。您也不能拥有结构类型,其大小根据结构中的数据而有所不同-至少并非没有使用一个(也是一个)柔性数组成员(FAM),但是您的代码尝试使用两个可变数组(因此它们不能成为FAM)。

您需要更多类似的东西:

typedef struct ytxModule{
    uint8_t nEncoders;
    uint8_t nDigital;
    uint8_t nAnalog;
    uint8_t nLedsPerControl;
} ytxModule;  // Add name for typedef

typedef struct{
    ytxModule components;
    uint8_t encPins[4][2];
    uint8_t encSwitchPins[4]; 
} ytxE41Module;

ytxE41Module module = {
    .components = {4, 0, 0, 16},
    .encPins = {
      {1, 0},  
      {4, 3},   
      {14, 15},  
      {11, 12}   
    },
    .encSwitchPins = { 2, 5, 13, 10 },
}; 

如果将.components.nEncoders初始化为4以外的其他值,则形状不会改变。根据您的需求,您可以考虑使用编译时可变值替换硬编码的4,但是您还需要一种方法来调整初始值设定项数组的大小以使其匹配,这可能是最好的选择。 ,在最坏的情况下难以理解。尚不清楚如何建立初始值。

使用灵活的数组成员

如果要使用灵活的数组成员,则必须组织一个类型来保存encSwitchPinsencPins数据的数组,并使用不同的符号来访问元素的元素。 FAM。

typedef struct ytxModule{
    uint8_t nEncoders;
    uint8_t nDigital;
    uint8_t nAnalog;
    uint8_t nLedsPerControl;
} ytxModule;

typedef struct
{
    ytxModule components;
    struct
    {
        uint8_t encPins[2];
        uint8_t encSwitchPins;
    } pins[]; 
} ytxE41Module;

您不能再为该数据类型使用初始化程序;您将动态分配内存,然后为分配的数据分配值:

// Data used for initializing structure
int n_pins = 4;
uint8_t encPins[][2] = {
    {  1,  0 },  
    {  4,  3 },   
    { 14, 15 },  
    { 11, 12 },   
};
uint8_t switchPins[] = { 2, 5, 13, 10 };

// Allocate and check allocation
ytxE41Module *mp = malloc(sizeof(*mp) + n_pins * sizeof(mp->pins[0]));
if (mp == NULL)
    return NULL;

// Assign values to allocated structure
mp->components = (ytxModule){ n_pins, 0, 0, 16};
for (int i = 0; i < n_pins; i++)
{
    for (int j = 0; j < 2; j++)
        mp->pins[i].encPins[j] = encPins[i][j];
    mp->pins[i].encSwitchPins = switchPins[i];
}

如果标记嵌入式结构类型,则可以初始化该类型的数组,然后使用memmove()(或memcpy())将单独的数组复制到FAM结构中。等等,如果结构中的数据量是固定的(例如,数组中的4个元素),则要简单得多,如答案的第一部分所示。

答案 1 :(得分:0)

我还有一个问题,如果我想初始化ytxE41Module数组怎么办?我认为编译器不喜欢这样:

ytxE41Module e41module[8] = {
    .components = {4, 0, 0, 16},
    .nextAddressPin = {6, 7, 8},
    .encPins = {
      {1, 0},  
      {4, 3},   
      {14, 15},  
      {11, 12}   
    },
    .encSwitchPins = { 2, 5, 13, 10 },
    .orientation = HORIZONTAL,
}; 

我也不:)

是否有办法保持这种状态?还是必须进行动态分配?

谢谢!