C语言结构体

C语言结构体初始化的四种方法

C语言聚合数据类型包括数组和结构体,其中数组中是相同类型的元素的集合,可以通过下标引用或之子很间接访问,但结构体各个成员可以是不同的数据类型。

结构声明

 完整的结构声明:struct tag {number-list} variable-list; 黑体部分至少要出现两个。

{number-list}和variable-list,每次声明新变量都要用单独的声明,而且每次声明后并不是同一种类型,尽管结构体内容完全一样

 1 struct {
 2     int a;
 3     float b;
 4     char c;
 5 }x;
 6 
 7 struct {
 8     int a;
 9     float b;
10     double c;
11 }*z;
12 
13 z = &x;//这样赋值是错误的,因为类型不一致,但C语言会忽略,C++会报错

  tag和{number-list},这样不用每次都使用单独的声明,只用struct tag即可对结构变量进行声明。

1 struct temp{
2     int a;
3     float b;
4     char c;
5 };
6 struct temp x;
7 struct temp *z;

 typedef、{number-list}和name,这样不用每次都使用单独的声明,只用name即可对结构变量进行声明,比上面的tag更加简洁,这时name是类型名,而不是结构标签。

1 typedef struct {
2     int a;
3     float b;
4     double c;
5 }temp;
6 temp x;
7 temp *z;

 结构体初始化

(1)定义时赋值,需要对应顺序,不能错位

 1 temp x = {1, 2.3, 4.66}; 

(2)定义后逐个赋值

temp x;
x.a = 1;
x.b = 2.3;
x.c = 4.66;

(3)定义时乱序赋值(C风格),这种方法在Linux内核(kernel)中经常使用,在音视频编解码库FFmpeg中也大量频繁使用,还是很不错的一种方式。

temp x = {
	.b = 2.3,
	.a = 1,
	.c = 4.66

};

(4)定义时乱序赋值(C++风格),类似于key-value键值对的方式

temp x = {
	b : 2.3,
	a : 1,
	c : 4.66
};

访问结构成员

(1)直接访问

 如上面声明的结构体变量所示,对x中的成员进行访问时,如下访问

int m = x.a; 
float = x.b;

(2)间接访问

 如果存在指向结构体的指针,则如下访问

int m = (*z).a;
int m = z->a;

结构的自引用

 结构内部包含一个类型为结构本身的成员,为自引用,高级的数据结构,链表和树都用到了该种结构。

声明时,编译器需知道结构体的大小,以便分配内存空间,所以不能直接用该结构体,否则会无限循环下去,无法知道结构体的大小。因此需要对该结构体成员使用指针。指针长度是固定的,取决于使用的机器和编译器,因此长度可知。

 1 typedef struct {
 2     int a;
 3     temp *b;
 4     double c;
 5 }temp; 
 6 //上面是错误的
 7 typedef struct selftemp_tag{
 8     int a;
 9     struct selftemp_tag *b;
10     double c;
11 }selftemp;

上面的声明是错误的,因为temp *b在声明之前就使用了。下面的声明中,定义了一个tag标签来解决该问题,同时标签前需加struct。

结构的互引用(不完整声明,还不知道怎么用)

 结构体之前互相引用,那么哪个结构应该首先声明呢?问题的解决方案是使用不完整声明,它声明一个作为结构标签的标识符

 1 struct B;
 2 
 3 struct A{
 4     struct B * partner;
 5     //其他声明
 6 };
 7 
 8 struct B{
 9     struct A * partner;
10     //其他声明
11 };

在A的成员列表中需要标签B的不完整声明,一旦A声明之后,B的成员列表也可被声明.(并不知道怎么用)

结构进行函数传参 

 结构变量用作函数参数进行传递时,如果传递整个结构体的话,结构体成员少时并没有影响,若成员很多,传递整个结构体会浪费内存空间,因此这时应该传递结构体指针,从而提高传递效率。

联合

 如果想在不同时刻把不同的东西存储在同一个位置,就需要用到联合,声明和结构体类似

union {
	float f;
	int i;
}fi;

当存储在同一位置的不仅仅是简单的整型或浮点型数值,而是完整的结构时,称为变体记录,具体程序实例参考《c和指针》P213

联合的各个成员具有不同的长度,联合的长度就是它最长成员的长度,因此如果没有动态内存分配的话,默认按照最长成员的长度进行内存分配,会造成内存空间的浪费。

联合的变量可以被初始化,但初始值必须是联合第一个成员的类型

union {
	float f;
	int i;
}fi = {0.5};

初始化的值必须位于一对花括号里面。

原文地址:https://www.cnblogs.com/qinguoyi/p/10130435.html