假设我们想统计学生的成绩,每一个学生的统计中都要包含以下内容:学生姓名、学号、成绩。我们已经知道,可以使用字符数组(char
)表示姓名,整型(int
)表示年龄,长整型(long int
)表示学号,浮点型(float
)表示成绩。这里每一位学生的数据都是一个整体。正因如此,我们可以使用结构体来表示它们。
在C语言中,结构体通过关键字 struct
声明 ,struct的全称为structured data type(结构化数据类型)。
在程序中,我们声明结构体的位置一般在函数外。如果把结构体的声明放在某一个函数内,比如主函数内,那么结构体就只能在主函数内应用。
struct Student
{
char name[50];
int age;
long int StudentID;
float score;
}student1;
上面的代码中,struct Student
是我们声明的数据类型,大括号内的代码块声明数据类型。student1
是对应于stuct Studnt
的变量名,每个结构化数据类型都可以对应多个不同的变量。
在创建结构化数据类型时,我们每一次都不得不使用struct
关键字。为了简化这种表述,可以在struct
之前使用typedef
为结构起一个别名。
typedef struct STUDENT//这里的typedef表示为结构起一个新的别名
{
char name[50];
int age;
long int StudentID;
float score;
}student;//stedent将成为struct STUDENT的别名
在C语言中,我们可以使用“点运算符”(.
)来访问结构体中的元素。
我们可以通过点操作符(.
)访问结构体zhangsan
中 的某一个元素:
#include
struct Student {
char name[50];
int age;
long int StudentID;
float score;
};
int main()
{
struct Student zhangsan = { "zhangsan",18,20230001,100};
printf("%f\n",zhangsan.score);
return 0;
}
如果我们想单独更改结构体中的某一个信息,我们不必要再次初始化整个结构体,可以直接针对某个元素更改数据。
#include
struct Student {
char name[50];
int age;
long int StudentID;
float score;
};
int main()
{
struct Student zhangsan = { "zhangsan",18,20230001,100};
printf("%f\n",zhangsan.score);
zhangsan.score=61;
printf("%f\n", zhangsan.score);
struct Student lisi = { "lisi",18,20230002,100 };
return 0;
}
下面是一个例子:
struct Student {
char name[50];
int age;
long int StudentID;
float score;
}class1[41];
结构体数组可以使用下面的代码在程序中直接进行初始化:
struct Student class2[2] = {
{"Alice", 30, 5.5},
{"Bob", 25, 5.8}
};
如果想从键盘或文件中导入数据,我们可以使用循环来声明数组(下面的代码使用的是标准输入):
#include
struct Student {
char name[50];
int age;
long int StudentID;
float score;
}student[41];
int main()
{
for (int i = 0; i <= 40; i++)
{
scanf("%s%d%ld%f", student[i].name, student[i].age, student[i].StudentID, student[i].score);
}
return 0;
}
结构体可以嵌套使用,即一个结构体成为了另一个结构体的元素。这种嵌套的结构体方便了我们模拟复杂的数据结构。
struct Date {
int day;
int month;
int year;
};
struct Student {
char name[50];
int age;
long int StudentID;
float score;
struct Date birthday;//这里是嵌套的结构体
}
从第3点可知,如果我们想要在某一个函数中调用结构体,结构体在实参与形参的传输过程中,还是会出现那个老问题——函数中参数地址和原地址不同。
为了解决这个问题,我们必须调用结构指针。
结构体与数组不一样,它的地址虽然相邻,但是却不能通过编号、加1和减1等方式进行访问。
.
操作符访问结构体中的元素,还可以使用->
符号访问结构体。struct Student *ptr = &zhangsan;
printf("%s is %d years old.\n", ptr->name, ptr->age);
printf("%s is %d years old.\n", (*ptr).name, (*ptr).age);
(*ptr)->name
而不是*ptr->name
*ptr->name
与*(ptr->name)
相同,如果这里的ptr
是指针变量,那么从第一步开始就无法完成。这篇文章中主要讲了结构体的有关知识点,可以说是比较详细的,可是在结构体应用方面是比较粗浅的,结构体还有更多的深奥的秘密等待着我们的学习与探寻。