char name[20]; //姓名 int num; //学号 char sex; //性别 int age; //年龄 float score; //成绩 char addr[30]; //家庭住址而且问题是这样写的话,只是定义了一个学生,如果要定义第二个学生就要再写一遍。这样不仅麻烦,而且很容易混淆。要是能定义一个变量,而且这个变量正好包含这六个项,即将它们合并成一个整体的话就好了。
struct结构体名
{
成员列表
};
struct STUDENT { char name[20]; int num; char sex; int age; float score; char addr[30]; }; //最后的分号千万不能省略说明:
struct STUDENT
{};
struct STUDENT
{
};
char name[20]; int num; char sex; int age; float score; char addr[30];成员名的命名规则与变量名相同。
int a;其中 int 是类型,而 a 是用这个类型定义的变量。结构体也是一样的,上一节只是声明了一个类型,而本小节要使用这个类型来定义变量,就这么简单。一个是类型,一个是用这个类型定义的变量。
struct STUDENT stud1, stud2;stud1 和 stud2 就是我们定义的结构体变量名。定义了结构体变量之后,系统就会为之分配内存单元。与前面讲的局部变量一样,如果 stud1 和 stud2 是在某个函数中定义的局部变量,那么就只能在该函数中使用。在其他函数中可以定义重名的结构体变量而不会相互产生影响。
struct STUDENT { char name[20]; int num; char sex; int age; float score; char addr[30]; }stud;这样就声明了一个结构体类型,并用这个类型定义了一个结构体变量 stud。这个变量是一个全局变量。
结构体变量名.成员名
如果成员名是一个变量名,那么引用的就是这个变量的内容;如果成员名是一个数组名,那么引用的就是这个数组的首地址。student1.num = 1207041;2) 如果结构体类型中的成员也是一个结构体类型,则要用若干个“.”,一级一级地找到最低一级的成员。因为只能对最低级的成员进行操作。
struct AGE { int year; int month; int day; }; struct STUDENT { char name[20]; int num; struct AGE birthday; float score; };完全可以写成:
struct STUDENT { char name[20]; int num; int year; int month; int day; float score; };但这样看起来很长、很乱。而使用结构体将 year、month、day 封装起来,代码看起来就会好很多。因为 year、month、day 都是生日的组成部分,所以将它们进行进一步的封装可以使代码看起来很整齐,很有层次感,便于操作。
# include <stdio.h> struct AGE { int year; int month; int day; }; struct STUDENT { char name[20]; int num; struct AGE birthday; //就有点类似于C++中的封装了 float score; }; int main(void) { struct STUDENT student1 = {"小明", 1207041, {1989, 3, 29}, 100}; printf("name : %s\n", student1.name); printf("birthday : %d-%d-%d\n", student1.birthday.year, student1.birthday.month, student1.birthday.day); printf("num : %d\n", student1.num); printf("score : %.1f\n", student1.score); return 0; }输出结果是:
printf("name : %s\n", &student1);原因是 %s 要求输出参数要么是字符数组名,要么是字符指针变量名,总之是 char* 型的。而 &student1 和 student1.name 在前面讲过,虽然它们是等价的,但它们的等价指的仅仅是“它们表示的是同一个内存空间的地址”,但它们的类型是不同的。&student1 是 struct STUDENT* 型的,而 student1.name 是 char* 型的,所以只能写 student1.name。
# include <stdio.h> struct AGE { int year; int month; int day; }; struct STUDENT { char name[20]; int num; struct AGE birthday; float score; }; int main(void) { struct STUDENT student1 = {"小明", 1207041, {1989, 3, 29}, 100}; return 0; }注意,同字符、字符数组的初始化一样,如果是字符那么就用单引号括起来,如果是字符串就用双引号括起来。
# include <stdio.h> # include <string.h> struct AGE { int year; int month; int day; }; struct STUDENT { char name[20]; //姓名 int num; //学号 struct AGE birthday; /*用struct AGE结构体类型定义结构体变量birthday, 即生日*/ float score; //分数 }; int main(void) { struct STUDENT student1; /*用struct STUDENT结构体类型定义结构体变量student1*/ strcpy(student1.name, "小明"); //不能写成&student1 student1.num = 1207041; student1.birthday.year = 1989; student1.birthday.month = 3; student1.birthday.day = 29; student1.score = 100; printf("name : %s\n", student1.name); //不能写成&student1 printf("num : %d\n", student1.num); printf("birthday : %d-%d-%d\n", student1.birthday.year, student1.birthday.month, student1.birthday.day); printf("score : %.1f\n", student1.score); return 0; }输出结果是:
# include <stdio.h> struct AGE { int year; int month; int day; }; struct STUDENT { char name[20]; int num; struct AGE birthday; float score; }; //分号不能省 int main(void) { struct STUDENT student1; /*用struct STUDENT结构体类型定义结构体变量student1*/ printf("请输入姓名:"); scanf("%s", student1.name); //不能写成&student1 printf("请输入学号:"); scanf("%d", &student1.num); printf("请输入生日:"); scanf("%d", &student1.birthday.year); scanf("%d", &student1.birthday.month); scanf("%d", &student1.birthday.day); printf("请输入成绩:"); scanf("%f", &student1.score); printf("name: %s\n", student1.name); //不能写成&student1 printf("num: %d\n", student1.num); printf("birthday: %d-%d-%d\n", student1.birthday.year, student1.birthday.month, student1.birthday.day); printf("score: %.1f\n", student1.score); return 0; }输出结果是:
scanf("%s",student1.name);也可以这么写:
scanf("%s", &student1.name);虽然在编译器中,&student1.name 代表的也是 name 的首地址,但是不建议初学者这么写,原因如下:
Copyright © 广州京杭网络科技有限公司 2005-2025 版权所有 粤ICP备16019765号
广州京杭网络科技有限公司 版权所有