use*_*345 8 c struct variable-length-array
我们可以声明一个可变长度的结构元素吗?
条件如下:
typedef struct
{
uint8_t No_Of_Employees;
uint8_t Employee_Names[No_Of_Employees][15];
}st_employees;
Run Code Online (Sandbox Code Playgroud)
Bas*_*tch 14
如果在C99或C11中编码,您可能希望使用灵活的数组成员(您没有给出明确的维度,但是您应该在运行时有一个关于它的约定).
typedef struct {
unsigned No_Of_Employees;
char* Employee_Names[]; // conventionally with No_of_Employees slots
}st_employees;
Run Code Online (Sandbox Code Playgroud)
对于任何阵列,柔性阵列构件的每个槽具有固定的尺寸.我正在使用指针(例如我的Linux/x86-64机器上的8个字节).
(在C99标准之前的旧编译器中,您可能会尝试给出0类似的尺寸,char* Employee_Names[0];即使它违反了标准)
然后你将使用例如分配这样的结构
st_employees* make_employees(unsigned n) {
st_employees* s = malloc(sizeof(s_employees)+n*sizeof(char*));
if (!s) { perror("malloc make_employees"); exit(EXIT_FAILURE); };
s->No_of_Employees = n;
for (unsigned i=0; i<n; i++) s->Employe_Names[i] = NULL;
return s;
}
Run Code Online (Sandbox Code Playgroud)
并且您可以使用(使用strdup(3)在堆中复制字符串)
st_employees* p = make_employees(3);
p->Employee_Names[0] = strdup("John");
p->Employee_Names[1] = strdup("Elizabeth");
p->Employee_Names[2] = strdup("Brian Kernighan");
Run Code Online (Sandbox Code Playgroud)
你需要一个void destroy_employee(st_employee*e)功能(作为练习留给读者).它可能应该循环i到free每一个e->Employee_Names[i],然后free(e);......
不要忘记记录有关内存使用的约定(谁负责调用malloc和free).阅读有关C动态内存分配的更多信息(并且害怕内存碎片和缓冲区溢出以及任何其他未定义的行为).
如果使用GCC年纪比GCC 5一定要与编制gcc -std=c99 -Wall,因为旧GCC编译器4的默认标准是C89.对于较新的编译器,请询问所有警告以及更多警告,例如gcc -Wall -Wextra......
TL; DR回答 - 不,你不能.
详细说明,让我引用C11,第6.7.2.1章,Structure and union specifiers(强调我的)
结构或联合的成员可以具有除可变修改类型之外的任何完整对象类型.[...]
并且,VLA是可变修改的类型.
但是,引用相同的标准,关于柔性阵列成员
作为一种特殊情况,具有多个命名成员的结构的最后一个元素可能具有不完整的数组类型; 这被称为灵活的阵列成员.[...]
所以,你可以做点什么
typedef struct
{
uint8_t No_Of_Employees;
uint8_t* Employee_Names[];
}st_employees;
Run Code Online (Sandbox Code Playgroud)
之后,您可以在运行时动态分配内存Employee_Names(Employee_Names[i]也可以)并使用它.