目录
一、定义和使用结构体变量
1.1创建结构体类型
1.2定义结构体类型变量
1.先声明结构体类型,在定义该类型的变量
2.在声明类型的同时定义
1.3结构体成员的类型
1.4结构体变量的初始化和引用
1.5结构体的访问
二、结构体传参
前言:C语言提供了一些由系统已定义好的数据类型,如:int,float,char等,用户可以在程序中用它们定义变量,解决一般的问题,但我们要处理的问题往往比较复杂,只有系统提供的类型还不能满足应用的需求,C语言允许用户根据自己建立一些数据类型,并用它来定义变量。
一、定义和使用结构体变量
1.1创建结构体类型
我们在描述一个学生时,学生的名字、性别、年龄、地址等,都是属于同一个学生的。如果将name,sex,age和addr分别定义为互相独立的简单变量,难以反映他们之间的内在联系,人们希望八这些数据组成一个组合数据,所以就有结构体来描述复杂类型。建立一个结构体类型,例如:
struct Student
{
int num; //学号为整形
char name[20]; //名字为字符串
char sex[5]; //性别为字符串
int age; //年龄为整形
}; //最后有一个分号
声明一个结构体类型的一般形式
struct 结构体名
{
//成员变量,是用来描述结构体对象的相关属性
成员列表
};
注意:结构体类型的名字是由一个关键字struct和结构体名组合而成的(例如:struct Student)。结构体名是由用户指定的,又称“结构体标记”,以区别于其他结构体类型。上面结构体中的Student就是结构体名。
花括号内是该结构体所包含的子项,称为结构体成员。上例中的num,name,age,sex等都是成员。
1.2定义结构体类型变量
前面只是建立了一个结构体类型,它相当于一个模型,并没有定义变量,其中没有具体的数据,系统也不会为之分配单元。相当于设计好图纸,但并没有建好房屋。为了能在程序中使用结构体类型的数据,应当定义结构体类型的变量,并在其中存放具体的数据。可以采取以下2种方法来定义结构体类型变量。
1.先声明结构体类型,在定义该类型的变量
struct Student
{
int num;
char name[20];
char sex[5];
int age;
};
int main()
{
struct Student s1;
struct Student s2;
return;
}
2.在声明类型的同时定义
struct Student
{
int num;
char name[20];
char sex[5];
int age;
}s1,s2;
这种方法定义的一般形式为
struct 结构体名
{
成员列表;
}变量名列表;
注意:声明类型和定义变量放在一起进行,能直接看到结构体的结构,比较直观,在写小程序时用此方法比较方便,但在写大程序时,往往要求对类型的声明和对变量的定义分别放在不同的地方,以使程序结构清晰,便于维护。
说明:
1。结构体类型和结构体变量是不同的概念。只能对变量赋值、存取或运算,而不能对一个类型赋值、存取或运算。在编译时,对类型是不分配空间的,只对变量分配空间。
2.结构体类型中的成员名可以与程序中的变量名相同,但二者不代表同一对象。例如:程序中可以另定义一个num,它与struct Student中的num不同,互不干扰。
下面我们通过图来加强对结构体类型和结构体变量的理解
1.3结构体成员的类型
结构的成员可以是标量、数组、指针,甚至是其他结构体。例如:
struct Date
{
int month;
int day;
int year;
};
struct Student
{
int num;
char name[20];
char sex[5];
int age;
struct Date birthday; //成员birthday属于struct Date类型
};
1.4结构体变量的初始化和引用
在定义结构体变量时,可以对它进行初始,即赋予初值。然后可以引用这个变量,例如:
struct Student
{
int num;
char name[20];
char sex[5];
int age;
};
int main()
{
struct Student s1 = { 114202,"张三","男",18 };
printf("%d %s %s %d\n", s1.num, s1.name, s1.sex, s1.age);
return 0;
}
(1)在定义结构体变量时可以对它的成员初始化。初始化列表是用花括号括起来的一些常量,这些常量依次赋给结构体变量中的各成员。
注意:是对结构体变量初始化,而不是对结构体类型初始化。
(2)可以引用结构体变量中成员的值,引用的方法为
结构体变量名 . 成员名
例如:已定义了s1为Student类型的结构体变量,则s1.num表示s1变量中的num成员,在程序中可以这样赋值,例如:
s1.num=114202;
“.”是成员运算符,它在所有的运算符中优先级最高,因此可以把s1.num作为一个整体来看待,相当于一个变量。
注意:不能企图通过输出结构体变量名来达到输出结构体变量的所有成员。
(3)若成员本身又属于一个结构体类型,则要用若干个成员运算符,一级一级的找到最低一级的成员。只能对低级的成员进行赋值或存取以及运算。
student.num (结构体变量student中的成员num)
student.brithday.month (结构体变量student中的成员brithday中的成员month)
(4)对结构体变量的成员可以像普通变量一样进行各种运算。
student2.score=student1.score; (赋值运算)
sum=student1.score+student2.score; (加法运算)
student1.age++; (自加运算)
(5)同类的结构体变量可以相互赋值,如:
student1=student2
(6)可以引用结构体变量成员的地址,也可以引用结构体变量的地址。例如:
scanf("%d",&student1.num);
printf("%o",&student1); //输出结构体变量student1的起始地址
//不能整体读入结构体变量/例如:
scanf("%d %d %s",&student1);
说明:结构体变量的的地址主要用作函数传参,传递结构体变量的地址。
1.5结构体的访问
p指向一个结构体变量stu,
- stu.成员名
- (*p).成员名
- p->成员名
二、结构体传参
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;
}
print2函数更好
原因:函数传参的时候,参数是需要压栈的。
如果传递一个结构体对象的时候,结构体过大,参数压栈的的系统开销比较大,所以会导致性能的 下降。
结论:结构体传参的时候,要传结构体的地址。
本次的内容到这里就结束啦。希望大家阅读完可以有所收获,同时也感谢各位读者的支持。文章有问题可以在评论区留言,博主一定认真认真修改,以后写出更好的文章。