在生活中往往很难用一个准确的数据类型来描述一个物体,例如一本书,描述它的书名、作者以及出版社,需要用字符型数组来表示。当描述它的价格时,需要整型变量来表示。所以需要定义一个结构体来修饰它,结构体是一些值的集合,这些值是结构体的成员变量。结构体的每个成员可以是不同类型的变量。
结构体声明的语法如下
struct tag–结构体名称
{
mumber_list;–结构体成员
}variable_list;–结构体变量
struct stu
{
char name[20];
char gender[10];
float score;
};//这里的分号不能忘
这里定义了一个结构体stu,成员有 char name[20];char gender[10];float score; 。
注意:
结构体的成员可以是变量、数组、指针,甚至可以是其他的结构体。
struct stu
{
char name[20];
char gender[10];
int age;
float score;
}s0; //定义一个全局结构体变量s0
int main()
{
struct stu s1 = {"zhangsan", "male", 18, 99.5f};//定义一个局部结构体变量s1并初始化
return 0;
}
下面我再举另一个例子
struct S
{
int i;
char c;
};
struct S1
{
float f;
struct S s;//结构体内嵌套声明结构体变量
double d;
};
int main()
{
struct S1 ss = { 3.14f,{18, 'c'}, 2.14};//嵌套定义并初始化结构体变量
return 0;
}
结构体成员的访问需要借助 “.” 成员访问操作符来进行访问。例如
#include
struct stu
{
char name[20];
char gender[15];
float score;
};
int main()
{
struct stu s1 = {"zhangsan", "male", 59.5f};
printf("%s %s %f\n",s1.name, s1.gender, s1. score);
return 0;
}
当指针访问结构体成员时,有时得到的并不是一个结构体变量,而是一个结构体指针。这时我们可以通过(->)操作符来进行访问
#include
struct stu
{
char name[20];
char gender[15];
float score;
};
void Print(struct stu* s1)
{
printf("%s %s %f\n", s1->name, s1->gender, s1->score);
}
int main()
{
struct stu s1 = {"zhangsan", "male", 59.5f};
Print(&s1);
return 0;
}
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;
}
在结构体传参中,如果使用传值调用的话,那么在创建数据压栈时,寄存器需要额外为结构体变量创建临时空间,程序性能会有所下降,如果使用创址调用,只需要通过指针对结构体变量进行操作,传参时可以大大减少寄存器的压力,这样可以使程序运行效率更高。
结论:在结构体传参时,尽量使用传址的方式进行传参。