结构体
结构是一些值的集合,这些值称为成员变量。结构体的每个成员变量可以是不同类型的变量。
结构体的声明
1.一般声明
struct tag//结构体类型名
{
member-list;//成员列表
//.......
}variable-list;//变量列表,全局变量
2.特殊的声明
//匿名的结构体类型,不完全的声明
struct
{
int a;
char b;
float c;
}x;
匿名的结构体声明不能同时定义两个,是非法的。
结构体的自引用
//代码1
struct Node
{
int data;
struct Node next;
};
//不可行,此时sizeof(struct Node)大小无法确定
//代码2
struct Node
{
int data;
struct Node* next;
};
//第二个成员变量用来存放内部结构体变量的地址
//代码3
typedef struct
{
int data;
Node* next;
}Node;
//错误
//代码4
typedef struct Node
{
int data;
struct Node* next;
}Node;
结构体变量的定义和初始化
struct Point
{
int x;
int y;
}p1; //声明类型的同时定义变量p1
struct Point p2; //定义结构体变量p2
//初始化
struct Point p3 = { 1 , 2};
struct Stu //类型声明
{
char name[15]; //名字
int age; //年龄
};
struct Stu s ={"zhangsan", 20}; //初始化
struct Node
{
int data;
struct Stu p;
struct Node* next;
}n1 = {10, {4,5}, NULL}; //结构体嵌套初始化
结构体成员访问
结构体变量访问成员函数是通过访问结构成员操作符( . )访问的。
如:rexp.member_name
如果是结构体变量的指针我们是通过访问结构指针成员( -> )访问的。
如:rexp->member_name
如何计算结构体(对齐数)大小?
- 第一个成员在与结构体变量偏移量为0的地址处。
- 从第二个成员开始,其他成员变量要对齐到对齐数的整数倍的地址处。 对齐数 = 默认对齐数与该成员大小的较小值。(vs中默认对齐数是8,linux中的默认对齐数是4)
- 结构体总的大小是最大对齐数(每个成员变量都有一个对齐数)的整数倍。
- 如果有结构体嵌套,嵌套的结构体对齐到自己的最大对齐数的整数倍,结构体的整体大小就是所有最大对齐数(包括嵌套结构体的对齐数)的整数倍。
结构体传参
struct S
{
int data[1000];
int num;
};
struct S = {{1,2,3,4}, 1000};
void print1(struct S s)
{
printf("%d\n"s.num);
}
void print2(struct S* ps)
{
printf("%d\n",ps->num);
}
int main()
{
print1(s); //传结构体
print2(&s); //传地址
return 0;
}
//传地址更好
//1.函数传参时,参数是需要压栈的,会有时间空间的系统开销
//2.传递结构体对象时,结构体过大,参数压栈开销过大,性能下降。