C语言结构体定义以及计算结构体的大小

C语言结构体

  • 结构体定义
  • 结构体变量的初始化
  • 结构体内存对齐

结构体定义

在C语言里,数组是存放相同数据类型的数据结构,而在实际生活中肯定不会全部是同种数据类型,那用什么来存储这些不同的数据类型, C语言提供了一种用户自定义的数据类型的数据结构----结构体,它可以存储不同的数据类型。
为了定义这种结构,我们需要使用 struct 语句,语句格式如下:

struct tag 		//struct 不能更改
{
	member-list1;
	member-list2;
}variable-list;

其中 tag 是结构体标签。
member-list 是标准的变量定义,例如 int num; 或 char arr[10] 等。
variable-list 是结构变量,定义在结构的末尾,最后一个分号之前,可以指定一个或多个结构变量。
注意:最后的分号不能省略。

下面是声明 Stu (学生) 结构类型的方式:

  1. 声明结构体的方式有很多,下面这种在声明类型的同时定义 stu 变量,因为是在 main 函数外创建的变量,所以属于全局变量,此时如果还要创建新的结构体变量,
    可以像这样:struct Stu stu1,stu2;
struct Stu			//声明学生类型
{
	char name[10];		//学生名字
	int age;			//学生年龄
}stu;				//声明的同时创建stu变量

//在main函数里创建
int main()
{
	struct Stu stu1, stu2;
	return 0;
}
  1. 下面这种声明方式,省略了tag标签,也叫匿名结构体,但是这个结构只能使用一次,后面就不能再创建新的变量,因为没有结构体标签,总不能 struct stu1 这样吧。
struct 
{
	char name[10];
	int age;
}stu;
  1. 下面这种声明方式,使用了 typedef 关键字,就可以使用 STU 作为类型来声明新的结构体变量了,例如 STU s1;
typedef struct
{
	char name[10];
	int age;
} STU;

STU s1;		//声明s1变量

在结构体的成员中可以包含其他的结构体(不能包含自己),也可以包含指向自己结构体类型的指针,例如下面,在结构体 B 中包含了结构体 A,也包含了一个指向自己结构体类型的指针:

struct A
{
	char a[10];
	int ai;
};
//下面这种是错的,不能包含自己
struct A
{
	struct A a;
	char a[10];
	int ai;
};
//下面是对的,通过指针来自引用
struct B
{
	char b[10];
	int bi;
	struct A a;		//可以包含其他结构体
	struct B* pb;		//可以包含一个指向自己结构体的指针
};

结构体变量的初始化

结构体变量的初始化,和其它类型一样,可以在定义时指定初始值,例如:

//创建Stu结构体,并初始化s1的值
struct Stu
{
	char name[10];
	int age;
}s1 = { "zhangsan",18 };
//创建s2变量
struct Stu s2 = { "lisi", 19 };

结构体里面还有结构体该怎么初始化?

struct A
{
	char c;
	int age;
};

struct Stu
{
	struct A a;
	char name[10];
	int age;
};

struct Stu s2 = { {'c',10},"lisi", 19 };

初始化结构体变量后,我们可以使用成员访问运算符 ( . ) ,通过 变量名.成员名 我们就能获取到结构体成员的值了。

int main()
{
	//s2.a.c 和 s2.a.age是因为s2里面还有一个结构体a,结构体a里有c和age
	printf("%c %d %s %d\n", s2.a.c, s2.a.age, s2.name,s2.age);
	//也可以按自己的顺序访问
	printf("%s %d %c %d\n", s2.name, s2.age,s2.a.c, s2.a.age);
	return 0;
}

运行结果:
C语言结构体定义以及计算结构体的大小_第1张图片
下面来到本次最重要的知识了:

结构体内存对齐

我们先来算下面这个结构体的大小,按照以前学的知识,char 占用一个字节,int 占用4个字节,那整个结构体的大小会不会就是5个字节?

struct Stu
{
	char c;
	int age;
};

当我们使用程序输出结构体的大小后,发现并不是上面说的一样占用5个字节,而是8个字节。

C语言结构体定义以及计算结构体的大小_第2张图片
首先我们得知道结构体的对齐规则:

  1. 结构体里的第一个成员在结构体变量偏移量为0的地址处。
  2. 其他成员则要对齐到对齐数的整数倍的地址处。
    这里的对齐数是编译器默认的一个对齐数与该成员大小的较小值
  3. 结构体总大小为最大对齐数(每个成员变量都有一个对齐数)的整数倍
    vs中对齐数默认是8。

还是来看例子:
C语言结构体定义以及计算结构体的大小_第3张图片

下面再来看一个例子:

C语言结构体定义以及计算结构体的大小_第4张图片
在上面两个例子中,都浪费了几个字节,这是因为内存对齐的原因,内存对齐的原因在于,为了访问未对齐的内存,处理器需要访问内存两次,而对齐的内存只需访问一次。这虽然浪费了空间,但提快了查询的时间。

C语言结构体定义以及计算结构体的大小_第5张图片
以上就是结构体的初始化以及如何计算结构体的大小。

你可能感兴趣的:(C语言,c语言,数据结构,c++)