在另一个结构中初始化和使用结构成员
Initializing and using struct members inside another struct
我需要在新结构 (struct2) 中使用之前声明的结构 (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] = {
任何帮助将不胜感激:)
最少的必要更改
您不能将 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
以外的值,这不会改变形状。根据您的需要,您可以考虑将 hard-coded 4
替换为 compile-time 可变值,但您还需要一种方法来调整初始化数组的大小以匹配,这很可能充其量是繁琐的,最坏的情况是难以理解的。目前尚不清楚初始化值是如何建立的。
使用灵活的数组成员
如果你想使用灵活的数组成员,你必须组织一个类型来保存 encSwitchPins
和 encPins
数据的数组,并使用不同的符号来访问元素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个元素),则要简单得多,如答案的第一部分所示。
我需要在新结构 (struct2) 中使用之前声明的结构 (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] = {
任何帮助将不胜感激:)
最少的必要更改
您不能将 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
以外的值,这不会改变形状。根据您的需要,您可以考虑将 hard-coded 4
替换为 compile-time 可变值,但您还需要一种方法来调整初始化数组的大小以匹配,这很可能充其量是繁琐的,最坏的情况是难以理解的。目前尚不清楚初始化值是如何建立的。
使用灵活的数组成员
如果你想使用灵活的数组成员,你必须组织一个类型来保存 encSwitchPins
和 encPins
数据的数组,并使用不同的符号来访问元素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个元素),则要简单得多,如答案的第一部分所示。