目录
二、结构体成员的访问
一、结构体的声明
结构的基础知识
结构体与数组有什么不同呢
结构是一些值的集合,这些值称为成员变量,结构的每个成员可以是不同的类型的变量
但是数组内部存放的是一组同类型元素的集合
结构的声明
struct tag//tag是标签名,是可以根据需求改变的
{
member-list;//成员名
variable - list;
}
注意:tag是标签名,是可以通过需求改变的
上代码:
#include<stdio.h>
struct stu
{
//结构体成员
char name[20];
int age;
char sex[10];
float score;
}s4,s5;//s4 s5也是结构体变量--全局的
int main()
{
struct stu s1, s2, s3;//s1 s2 s3也是结构体变量--局部的
return 0;
}
在这段代码中,s4,s5与s1,s2,s3都是结构体变量,那么它们有什么区别呢?
s4,s5是作用于全局的结构体变量,而s1,s2,s3则是局部的结构体变量
在进行结构体声明的时候,我们要注意在结构体的末尾加上分号!
结构成员的类型
一起来观察这段代码:
#include<stdio.h>
struct stu
{
//结构体成员
char name[20];
int age;
char sex[10];
float score;
}s4,s5;//s4 s5也是结构体变量--全局的
int main()
{
struct stu s1, s2, s3;//s1 s2 s3也是结构体变量--局部的
return 0;
}
我们可以很明显的发现:结构的成员可以是标量、数组、指针,甚至是其它的结构体,换而言之,结构的每个成员可以是不同的类型的变量!
结构体变量的定义和初始化
有了结构体变量,那么如何定义变量呢?
struct point
{
int x;
int y;
}p1;//定义结构体变量p1
struct point p2;//定义结构体变量p2
我们来看一段结构体初始化的代码:
struct stu//类型声明
{
char name[20];//姓名
int age;//年龄
};
struct stu s = { "zhangsan",20 };//初始化
struct node
{
int data;
struct stu p;
struct node* next;
}n1={10,{4,5},NULL};//结构体嵌套初始化
struct node n2 = { 20,{5,6},NULL };//结构体嵌套初始化
在这段代码中,我们展示了结构体初始化和结构体嵌套初始化两种初始化的过程 ,可以发现,在结构体初始化的时候,结构体也可以像函数一样发生嵌套
二、结构体成员的访问
结构变量的成员是通过点操作符(.)访问的,点操作符接受两个操作数,例如:
那么出了点操作符之外,有没有别的方法可以对结构体成员进行访问呢?
答案是有的,我们可以使用指针来访问结构体成员
在使用指针访问结构体成员时,我们可以选择使用点操作符,也可以使用->操作符来对结构体成员进行访问,
结构体指针访问指向变量的成员
有时候我们得到的不是一个结构体变量,而是指向一个结构体的指针,这时候我们又该如何访问成员呢?
上代码:
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函数
原因:
函数在传参数时,参数是需要压栈的
如果传递一个结构体变量的时候,结构体过大,参数压栈的系统开销比较大,所以会导致性能的下降
结论:
结构体传参的时候,要传结构体的地址