“教小白精通编程”系列之“C语言教程” (版权所有,不得转载,擅自抄袭转载将承担法律责任)
结构 struct
C语言的内在类型有
1) 基础类型
2) 指针类型
3) 数组类型
这些类型只能表示一些低层的概念,而实际问题或应用中概念是千变万化的,比如员工管理中的员工、游戏中的坦克等都是一些应用中涉及到的比较高层的概念。如何表示这些概念?C语言提供了用户自定义类型的手段,如struct(结构类)型、enum(枚举)类型等。
数组是一组同类型元素的顺序集合,而结构struct则是表示一个对象的多个不同属性的集合,比如编写一个学生成绩单程序,一个学生有:姓名、分数等属性,一个图书管理程序中一本图书有: 书名、作者、出版社、出版日期、书号等属性。C语言可以让程序员用关键字struct定义各种用户自定义的结构(struct)数据类型,这些结构类型(如同int类型表示整数一样)用于抽象表示实际问题中遇到的各种概念或对象的各种属性。定义好某种结构类型如“struct student”后,就可以从这种结构类型“struct student”的各种具体变量。
1. 定义一个结构类型的格式如下:
struct name{
members; /*成员变量*/
};
例如:
struct student {
char student_name[20]; /*学生的姓名*/
float score; /*成绩的分数*/
};
如同内在类型的变量一样,我们也可以定义结构类型的变量,如:
struct student stu1,stu2; /*定义了struct student类型的2个变量stu1 和 stu2 */
2. 可以通过成员访问运算符’ . ‘ 访问结构类型变量的成员:
tu1.score = 80.5;
strcpy(stu1.name,"Li Ping");
如下是一个简短完整的程序:
#include <stdio.h>
struct student {
char student_name[20]; /*学生的姓名*/
float score; /*成绩的分数*/
};
void main(){
struct student stu;
strcpy(stu.name,"Li Ping"); stu.score = 80.5;
printf("the score of student %s is: %8.4f\n", stu.name,stu.score);
printf("请输入修改的学生姓名:\n");
scanf("%s" , stu.name);
printf("the score of student %s is: %8.4f\n", stu.name,stu.score);
}
3. 结构变量的指针、结构变量的指针变量(简称为 结构指针变量)
struct student stu;
struct student * p ; /* p是一个存储struct student类型变量地址(指针)的指针变量,其类型是struct student * */
p = &stu; /* struct student* 类型的指针变量p存储的是stu的指针 */
strcpy(p->name, "Wang Hao"); /* p->name: 通过间接访问运算符->访问结构指针变量p指向的student类型变量stu的成员name */
p->score = 50.5;
(*p).score = 70.7; /* 这里的*p : 通过取内容运算符号*作用指针变量p即*p获得p指向的那个变量stu */
注: 我们学习了新的间接访问运算符->, 也复习了取内容运算符 *
4. 结构变量、结构变量指针 作为函数参数
可以将一个结构变量或结构变量的指针作为函数参数传给一个函数。这个函数的形式参数类型必须也是结构变量或结构变量指针。
struct student{
char name[10];
double score;
}
void Print(struct student stu){
printf("%s,%lf",stu.name,stu.score);
}
void main(){
struct student s;
scanf("%s %lf",&(s.name),&(s.score)); /* 因数组名name就是数组的其实地址,也可以:scanf("%s %lf",s.name,&(s.score));*/
Print(s); /*将实际参数s的值拷贝给形式参数stu,进入Print函数执行*/
}
下面代码存在什么问题?
struct student{
char name[10];
double score;
}
void Print(struct student stu){
printf("%s,%lf",stu.name,stu.score);
}
void Scanf(struct student stu){
scanf("%s %lf",&(stu.name),&(stu.score));
}
void main(){
struct student s;
Scanf(s); /*将实际参数s的值拷贝给形式参数stu,进入Scanf函数执行*/
Print(s); /*将实际参数s的值拷贝给形式参数stu,进入Print函数执行*/
}
Scanf函数中的形式参数stu确实可以得到键盘的输入,但它是和main中的实际参数s互不相干的,当Scanf执行完后,其中的stu就销毁了,而main中的s没有任何变化。
那么,如何修改Scanf? 答案: 将main的变量s的指针作为参数传给被调用函数,被调用函数通过这个指向变量s的指针就可以访问修改变量s了。
struct student{
char name[10];
double score;
}
void Print(struct student stu){
printf("%s,%lf",stu.name,stu.score);
}
void Scanf(struct student *stu){
scanf("%s %lf",&(stu->name),&(stu->score));
}
void main(){
struct student s;
Scanf(&s); /*将s的指针作为实际参数值拷贝给形式参数stu,进入Scanf函数执行*/
Print(s); /*将实际参数s的值拷贝给形式参数stu,进入Print函数执行*/
}
5. 结构数组作为函数参数
编写一个学生成绩表的输入输出程序,从键盘输入学生成绩,然后输出这些学生成绩。提示:所有学生成绩可以保存在一个“struct student”类型的数组中。
struct student{
char name[10];
double score;
}
void Print(struct student stu){
printf("%s,%lf\n",stu.name,stu.score);
}
void Scanf(struct student *stu){
scanf("%s %lf",&(stu->name),&(stu->score));
}
void main(){
sturct student students[100]; /*最多能放100个学生成绩*/
int n=0; /*实际学生人数*/
do{
Scanf(&students[n]);
if(s.score<0) break; /*推出循环*/
n++; //新输入一个学生信息,人数增加1
}while(1);
for(int i = 0 ; i<n ;i++)
Print(students[i])
}
我们可以将上面程序的输入输出分别变成2个函数,代码如下:
struct student{
char name[10];
double score;
}
void Print(struct student stu){
printf("%s,%lf\n",stu.name,stu.score);
}
void Scanf(struct student *stu){
scanf("%s %lf",&(stu->name),&(stu->score));
}
int Scanf_all(struct student students[]){
int n=0; /*实际学生人数*/
do{
Scanf(&students[n]);
if(s.score<0) break; /*推出循环*/
n++; //新输入一个学生信息,人数增加1
}while(1);
return n;
}
void Print_all(struct student students[],int n ){
for(int i = 0 ; i<n ;i++)
Print(students[i])
}
void main(){
sturct student students[100]; /*最多能放100个学生成绩*/
int n = Scanf_all(students);
Print_all(students);
}
练习
您的打赏是对我最大的鼓励!