一.结构体概念
二.结构体的声明
struct tag//tag需要做到见名知意,可以省略,但不建议省略。起到了标签的作用 { member-list;//成员列表,不可省略,C中不可以定义孔结构体 }variable-list;//变量列表,建议省略,结构体变量按需定义
例如:描述一个学生信息
结构体成员变量可以是任何类型,甚至是其他结构体类型。
特殊的声明:在定义结构体的时候可以不完全的声明
struct //匿名结构体类型,省略了标签tag,没有错误但是一般情况下不建议这样做,容易混淆 { int a; char b; float c; }x; struct { int a; char b; float c; }a[20],*p;
试试下面这样可以吗
p = &x;
三.结构体成员的访问
例如:
假如得到的是一个结构体指针,就可以用" . "或"->"操作符来访问结构体成员:
struct Stu { char name[20]; int age; }; struct Stu s; void print(struct stu* ps) { printf("name = %s age = %d\n", (*ps).name, (*ps).age); printf("name = %s age = %d\n", ps->name, ps->age); }四.结构体的自引用
//代码1 struct Node { int data; struct Node next; }; //问:sizeof(struct Node)结果是多少?
//代码2 struct Node { int data; struct Node* next; }; //问:sizeof(struct Node)结果是多少
所以,在结构体自引用的时候一定要是引用自身结构体的指针。否则会不断在栈上递归式地开辟空间,耗时耗空间相当大。
五.结构体的不完整声明
struct B;//结构体不能再声明之前就使用 struct A { int a; int b; int arr1[4]; int arr2[2][2]; struct B* p; } struct B { int a; int b; char c; struct A* q; };
六.结构体变量的定义和初始化
开头前面提到结构体和数组一样是聚合类型,所以结构体的初始化和数组可以说是一模一样
先是声明了一个结构体类型,再顺手定义了一个结构体变量x,同时为变量赋值。上面两种方式都可以。
七.结构体内存对齐
(1)什么是内存对齐?
看下面两个结构体大小相同吗?
struct A { char a; int b; char c; }; struct B { char a; char c; int b; }; int main() { printf("%d\n", sizeof(struct A)); printf("%d\n", sizeof(struct B)); system("pause"); return 0; }
(2)为什么要有结构体对齐?
(3)怎么对齐?偏移量整除自身对齐数就是对齐了
(4)对齐规则:记住四句话:
举个栗子,有两个结构体A和B,A嵌套在B中,A就要对齐到自身最大对齐数(本结构体成员的最大对齐数)的整数倍处,而B结
构体的整体大小最所有成员最大对齐数的整数倍。其实就是第三句话。
(5)其实简单点可以这样理解,存放一个数据的时候求出其偏移量,再用偏移量除以大小,如果能整除就将数据存到这个位
置,若果不行就往后移。最后要保证总大小是最大对齐数的整数倍。
(6)关于#pragma pack()的使用,这是用来自定义对齐数的,只不过括号里面能填的只有1,2,4,8或者16
六.附送一些练习题
#include <stdio.h> struct s1 { char a; int b; char c; }; struct s2 { char a; char c; int b; }; struct s3 { double a; char b[3]; int c; short d; }; struct s4 { double a; char b[3]; int c; }; struct s5 { char a; struct s3 s3; double d; }; struct s6 { char a; struct s4 x; char b[3]; char *c[2]; double e; struct s2 f[2]; char g; }; int main() { printf("s1:%d s2:%d s3:%d s4:%d s5:%d s6:%d\n",\ sizeof(struct s1),\ sizeof(struct s2),\ sizeof(struct s3),\ sizeof(struct s4),\ sizeof(struct s5),\ sizeof(struct s6)); return 0; }
文章来源: 自定义类型――结构体