该系列为本人的学习笔记,主要由本人整理书写而成。部分内容来自教材、视频课程等,不能保证完全原创性。
萌新的学习笔记,写错了恳请斧正。
# 结构体(联合体)嵌套
结构体、联合体可以嵌套,也就是说结构体(联合体)的成员也可以是结构体(联合体)
# 嵌套时内嵌结构体(联合体)不创建变量(匿名)
如果嵌套时内嵌结构体(联合体)不创建变量(匿名),内嵌结构体(联合体)的成员会被认为是外围结构体(联合体)的成员,如果外围结构体(联合体)也是匿名的,那么就递归应用此规则:
#include <stdio.h> | |
struct | |
{ | |
int x; | |
struct | |
{ | |
int y; | |
union | |
{ | |
int z; | |
char c; | |
}; | |
}; | |
} a; | |
int main() | |
{ | |
a.z = 1; | |
printf("%d\n", a.c); | |
return 0; | |
} |
注意:此匿名非彼匿名,结构体类型依旧可以有名字,但是不能内嵌结构体只能有其声明部分而不能在后面加成员变量名
# 嵌套时内嵌结构体(联合体)创建变量(非匿名)
当嵌套时内嵌结构体(联合体)创建变量(非匿名),则需要通过访问操作符先访问这个内嵌结构体类型的成员,再访问其中的成员,如果外围结构体(联合体)也是非匿名结构体,那么就递归应用此规则:
#include <stdio.h> | |
struct S1 | |
{ | |
struct S2 | |
{ | |
union U1 | |
{ | |
union U2 | |
{ | |
int n1; | |
int n2; | |
} u2; | |
int n3; | |
} u1; | |
int n4; | |
} s2; | |
int n5; | |
} s1; | |
int main() | |
{ | |
s1.s2.u1.u2.n1 = 1; | |
printf("%d\n", s1.s2.u1.n3); | |
return 0; | |
} |
同样的,这里的非匿名也与匿名结构体无关,结构体类型也可以没有命名,但是内嵌结构体后面应该加成员变量名
# 嵌套初始化
这边 C 官网上讲的足够清楚了,链接在此
# 柔性数组
在 C99 标准以后,结构体的最后一个成员被允许是一个未知大小的数组,这就叫柔性数组
这个未知大小当然不是真的未知,而是 “可动态分配”
比方说:
struct S | |
{ | |
int i; | |
long arr[]; | |
}; |
或者写成:
struct S | |
{ | |
int i; | |
long arr[0]; | |
}; |
特点:
- 柔性数组成员前必须至少包含一个其他成员
- 用 sizeof 返回包含柔性数组的结构体的大小时,忽略柔性数组后正常计算
- 包含柔性数组的结构体不能作为数组成员或者其他结构体的成员
- 如果创建包含柔性数组的结构体变量最好使用动态内存分配(见下)
# 柔性数组的使用
如下便是给柔性数组分配了 40 个长整型的空间
#include <stdio.h> | |
#include <stdlib.h> | |
typedef struct | |
{ | |
int i; | |
long arr[]; | |
} stt; | |
int main() | |
{ | |
stt* p = (stt*)malloc(sizeof(stt) + 40 * sizeof(long)); | |
if (p == NULL) | |
{ | |
perror("malloc-p"); | |
exit(EXIT_FAILURE); | |
} | |
p->i = 40; | |
for (int i = 0; i < 40; i++) | |
p->arr[i] = i + 1; | |
for (int i = 0; i < 40; i++) | |
printf("%2ld\t", (*p).arr[i]); | |
free(p); | |
p = NULL; | |
return 0; | |
} |