为什么要使用结构体
在我们c语言中提供了许多基本数据类型,比如Int,char float 等,那么比如我现在想去存贮一个学生的信息,其中包含姓名,年龄,成绩等。那么此时我们使用基本数据类型就会非常的麻烦,而c语言中提供了一种属性,叫做结构体,结构体可以对我们的一些基本属性进行封装。十分的方便。
结构体的定义
定义结构体
定义结构体非常简单,我们只需要使用struct关键字即可。使用struct 类型名,即可定义一个结构体。例如
struct student//结构体定义
{
};
这里初学者会犯一个误区,student是结构体类型的名字,不是结构体变量的名字。
成员变量
在大括号中的值就叫做成员变量。我们可以包括多重类型。
struct student
{
int age;//年龄
float score;//分数
char *name;//不使用数组是因为数组占用空间。
//还可以添加许多类型...
};
注意,此时我们定义的结构体是一种类型,不是变量!!!!
空结构体
空结构体里面没有任何的属性,需要我们后面手动添加。
struct empty
{
};
匿名结构体
顾名思义,这个结构体可以没有名字
struct
{
};
但是这样的话这个结构体在后续的程序中,就没有办法得到使用。所以我们就会在这个后面加上变量名。
struct student
{
}stu1,stu2;//这个是变量!!!
使用typedef
我们平时定义变量 int a ;
在结构体中我们使用结构体定义变量就是
struct student
{
int age;//年龄
float score;//分数
char *name;//不使用数组是因为数组占用空间。
//还可以添加许多类型...
};
int main()
{
struct student stu1;
}
在上述程序中我们使用student类型定义了一个名叫stu1的变量。
但是我们每次定义变量都要使用struct student 很麻烦,这时候就要用到typedef了。
typedef就是给类型重新命名
typedef struct student
{
int age;
float score;
}stu1;
int main()
{
stu1 stu2;
}
这个结构体的名字不是student了,而是stu1。
我们使用了stu1这个类型定义了一个stu2的变量。
结构体的嵌套
typedef struct Birthday
{
int year; //年份
int month; //月份
int day; //日
}Birthday;
struct Student
{int id; //学号
char *name;
int age; //年龄
fLoat score; //成绩
Birthday birthday;
} ;
我们可以看出student 结构体里面嵌套了一个birthday 结构体。他是支持很多层嵌套的。
结构体变量
定义结构体变量
在上方我们所定义的结构体,他是不占用内存的,就想int float double 一样,它是一种类型。
typedef struct student
{
int age;
float score;
}stu1;
int main()
{
stu1 stu2,stu3;
}
使用stu1这个类型定义了stu2,stu3两个变量,stu2,stu3就是变量名字。
typedef struct student
{
int age;
float score;
}stu1 stu3;//也可以在stu1后面直接定义一个stu3。
int main()
{
stu1 stu2;
}
结构体变量赋值
typedef struct student
{
int age;
float score;
}student;
int main()
{
student stu1 = {10,100};
student stu2 = {20,100};
}
我们定义了2个学生的结构体变量分别是stu1,stu2。注意student 是类型不是变量!!!
访问成员结构体成员
访问成员变量使用.操作符
格式为 变量名.
typedef struct student
{
int age;
float score;
}student;
int main()
{
student stu1 = {10,100};
student stu2 = {20,100};
printf("%d ,%f",stu1.age,stu1.score);//使用了.操作符来找到数值
}
结构体函数的参数
typedef struct student
{
int age;
float score;
}student;
void fun(Student stu)//函数 stu这个变量用来接收stu1,stu2
{
printf("%d ,%f",stu.age,stu.score);
}
int main()
{
student stu1 = {10,100};
student stu2 = {20,100};
fun(stu1);//值传递
fun(stu2);
}
结构体指针
之前的函数中,我们使用的值传递,值传递理论是拷贝,所以效率比较低。所以我们要学习一下结构体指针
定义结构体指针
typedef struct student
{
int age;
float score;
}student;
void fun(Student *stu)//函数 stu这个变量用来接收stu1,stu2
{
printf("%d ,%f",stu->age,stu->score);//指针使用->来访问成员变量
}
int main()
{
student stu1 = {10,100};
student stu2 = {20,100};
student * p = &stu1;
fun(p);//传址操作
}
指针引用有两种情况
1.指针名->结构体成员变量
2.(*指针名).结构体成员变量
结构体的内存计算
计算方式
我们可以sizeof来计算这个结构体占用多少字节
typedef struct student
{
int age;
float score;
}student;
void fun(Student stu)//函数 stu这个变量用来接收stu1,stu2
{
printf("%d ,%f",stu.age,stu.score);
}
int main()
{
student stu1 = {10,100};
student stu2 = {20,100};
fun(stu1);//值传递
fun(stu2);
printf("学生结构日所占的字节数%d",sizeof(student));
}
得到的结果是8,因为int 占据4个字节,float也占据4字节
内存对齐
typedef struct A
{
int a;
char c;
}A;
int main()
{
printf("A结构体所占的字节数%d",sizeof(A));
}
结果是8,而不是5为什么呢
因为在计算时会考虑内存对齐的问题。char 类型是1字节,而int 类型是4字节。没有办法对齐
再举个例子
typedef struct A
{
int a;//4字节
char c;//1字节
char a[3];//3字节
}A;
int main()
{
printf("A结构体所占的字节数%d",sizeof(A));
}
结果为8
结构体数组
之前我们使用了stu1定义了结构体变量,现在我们使用数组来存贮信息
typedef struct student
{
int age;
float score;
}student;
int main()
{
student stu1 = {10,100};
student stu2 = {20,100};
student stu3[2] = {{10,100},{20,100}};
}
结构体数组输出
数组引用
数组名[下标].结构体成员变量
typedef struct student
{
int age;
float score;
}student;
int main()
{
student stu1 = {10,100};
student stu2 = {20,100};
student stu3[2] = {{10,100},{20,100}};.
for(int i =0;i<2;i++)//输出
printf("%d %f ",stu3[i].age,stu3[i].score);
}