结构体简介
- C语言提供了一些由系统已定义好的数据类型,如:int,float,char等,用户可以在程序中用它们定义变量,解决一般的问题,但是人们要处理的问题往往比较复杂,只有系统提供的类型还不能满足应用的要求,C语言允许用户根据需要自己建立一些数据类型,用它来定义变量。
- 在前面所见到的程序中,所用的变量多数是互相独立,无内在联系的。例如定义了变量a,b,c,它们都是单独存在的变量,在内存中的地址也是互不相干的,但在实际生活和工作中,有些数据是有内在联系的。
- 例如:一个学生的学号、姓名、性别、年龄、成绩、家庭住址等,是属于一个学生的。如下图:
- 人们想把这些数据组成一个组合数据,例如定义一个student的变量,在这个变量中包括学生的学号等信息。这样,使用起来就方便多了。
那能否用一个数组来存放这些数据呢?显然不行,因为一个数组中只能存放同一类型的数据。 - 为了实现上述功能,C语言允许用户自己建立由不同类型数据组成的组合型的数据结构,它被称为结构体。
结构体的声明
结构体是一些值的集合,这些值称为成员变量。结构体的每个成员可以是不同类型的变量。
结构的声明
struct tag{
member_list;
} variable_list;
例:描述一个学生
typedef struct Student{
char name[1024];
int age;
char sex[5];
char id[20];
char address[1024];
double score;
} Student;
结构体成员的类型
结构体的成员可以是标量、数组、指针,甚至是其他结构体。
结构体变量的定义和初始化
有了结构体类型,如何定义变量呢?
代码示例
方法一
struct Point{
int x;
int y;
} p1;
struct Point p2;
struct Point p3 = {x, y};
方法二
typedef struct Point{
int x;
int y;
} Point;
Point p1;
Point p2 = {x, y};
嵌套定义
typedef struct Birthday {
int year;
int month;
int day;
} Birthday;
typedef struct Student {
char name[1024];
int age;
struct Birthday bir;
} Student;
Student stu = { "Sss", 24, { 1995, 9, 16 } };
结构体成员的访问
结构体变量成员是通过点操作符.访问的。点操作符接受两个操作数。
我们可以看到stu有成员name、age和score;那该如何访问它们呢?
strcpy(stu.name, "Sss");
s.age = 24;
s.score = 100.0;
结构体指针访问指向变量的成员,有时候我们得到的不是一个结构体变量,而是指向一个结构体的指针。那该如何访问成员。
strcpy((*pstu).name, "Sss");
(*pstu).age = 24;
(*pstu).score = 100.0;
strcpy(pstu->name, "Sss");
pstu->age = 24;
pstu->score = 100.0;
结构体传参
代码演示
#include <stdio.h>
#include <stdlib.h>
typedef struct Student {
char name[1024];
int age;
double score;
} Student;
void stuDisplay1(Student stu){
printf("stuDisplay1: \n");
printf("name: %s\tage: %d\tscore: %.1f\n",
stu.name, stu.age, stu.score);
}
void stuDisplay2(Student* stu){
printf("stuDisplay2: \n");
printf("name: %s\tage: %d\tscore: %.1f\n",
stu->name, stu->age, stu->score);
}
int main(){
Student stu = {
"Sss", 24, 100.0
};
stuDisplay1(stu);
stuDisplay2(&stu);
system("pause");
return 0;
}
运行结果
上面的两个打印函数哪个好些?
首选stuDisplay2。形参是实参的拷贝,第一种打印方式,需要将整个结构体变量拷贝一份,开销太大。讲解函数栈帧时,我们讲过函数传参的时候,参数是需要压栈的。如果传递一个结构体对象的时候,结构体过大,参数压栈的系统开销比较大,会导致性能下降。