目录
1. 结构体的声明
1.1 结构的基础知识
1.2 结构的声明
1.3 结构成员的类型
1.4 结构体变量的定义和初始化
2. 结构体成员的访问
2.1(.)操作符
2.2(->)操作符
3.结构体传参
1. 结构体的声明
1.1 结构的基础知识
结构体是一些值的集合,这些值称为成员变量。结构的每个成员可以是不同类型的变量。
对比数组,数组是一类同类型的值的结合
1.2 结构的声明
struct tag
{
member-list;//结构体成员(属性)列表
}variable-list;//创建的结构体类型变量列表
例如描述一个学生:
struct Stu
{
char name[20];//名字
int age;//年龄
char sex[5];//性别
char id[20];//学号
};//分号不能丢
1.3 结构成员的类型
结构的成员可以是标量、数组、指针,甚至是其他结构体。
1.4 结构体变量的定义和初始化
我们先创建一个结构体:
、
struct Stu
{
char name[20];//名字
int age;//年龄
char sex[5];//性别
char id[20];//学号
};//分号不能丢
因为我们创建的的是一个类型,结构体类型,他和整型,浮点型这些类型的含义是一样的,那比如我们就利用上面的学生结构体类型来创建一个个变量:
struct Stu s1;//这个是s1就是一个结构体变量,他的类型是struct Stu
这是单独创建的办法,当然也可以在创建结构体类型的时候就直接创建变量:
struct Stu
{
char name[20];//名字
int age;//年龄
char sex[5];//性别
char id[20];//学号
}s2;//分号不能丢
//这里的上s2就是创建的结构体类型的变量,类型是struct Stu
有时候如果我们觉得,在创建变量的时候,要写出完整的结构体类型比如上面的s1变量的创建觉得有些麻烦,那我们就可以对结构体类型进行类型重定义:
typedef struct Stu
{
char name[20];//名字
int age;//年龄
char sex[5];//性别
char id[20];//学号
}Stu;//分号不能丢
//这里的Stu就是我们重定义的类型
Stu = struct Stu
我们这次创建S1变量的时候就可以这样写:
Stu s1 ;
那我们对于上述结构体初始化:结构体初始化使用{}
1.struct Stu s1 = {0};//这种就是直接简单粗暴把所有的值都初始化为0
2.struct Stu s2 = {"zhangsan",10,男,1234};//这里我们就初始化好了一个结构体变量
对于我们结构体嵌套结构体的定义和初始化:
struct Point
{
int x;
int y;
};
struct Node
{ int data;
struct Point p;
struct Node* next;
}n1 = {10, {4,5}, NULL}; //结构体嵌套初始化
struct Node n2 = {20, {5, 6}, NULL};//结构体嵌套初始化
2. 结构体成员的访问
2.1(.)操作符
结构体成员的访问使用‘.’操作符
点操作符接受两个操作数。
首先我们创建一个结构体变量:
struct Stu
{
int age ;
char name[20];
};
现在我想对结构体的两个成员单独赋值应该怎么做呢?
理由点操作符:
//先创建一个结构体类型变量
struct Stu s1 ;
//对年龄进行赋值
s1.age = 20;
//对名字进行赋值
s1.name = [20];
2.2(->)操作符
结构体指针访问指向变量的成员 有时候我们得到的不是一个结构体变量,而是指向一个结构体的指针。 那该如何访问成员。(因为有时结构体作为函数参数进行传参就会传递结构体的地址,这个时候就会用到结构体类型的指针,下面讲) 如下:
struct Stu
{char name[20];int age;
};
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);
}
int main()
{struct Stu s = {"zhangsan", 20};print(&s);//结构体地址传参return 0;
3.结构体传参
当结构体作为函数参数进行传递是,可以用结构体类型参数进行接收,相当于在函数中拷贝一份一模一样的结构体,也可以传地址,用指针进行操作,如下:
struct S
{int data[1000];int num;
};
struct S 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;
}
上面的 print1 和 print2 函数哪个好些?
答案是:首选print2函数。
原因: 函数传参的时候,参数是需要压栈的。 如果传递一个结构体对象的时候,结构体过大,参数压栈的的系统开销比较大,所以会导致性能的 下降。
结论: 结构体传参的时候,要传结构体的地址。