C程序设计--结构体(结构体和函数之间的参数使用)

版权声明:本文由 Micheal 超 博客 创作,转载请附带链接,有问题欢迎交流。 https://blog.csdn.net/qq_42887760/article/details/84076506

结构体类型(掌握点):

  • 建立结构体类型
  • 定义结构体类型变量
  • 初始化结构体和引用结构体变量(3种方法,见下)
  • 使用结构体数组
  • 结构体指针(重要)
    1. 指向结构体变量的指针
    2. 指向结构体数组的指针

代码案例

#include<stdio.h>
#include<string.h>

//定义结构体

struct Student{
	long num;//学号为整型
	char name[20];//姓名为字符串
	char sex;//性别为字符型
	int age;//年龄为整型
	float score;//成绩为实型
	char addr[30];//地址为字符串
};	//注意最后有一个分号

int main(){

	//1.指向结构体变量的指针
	struct Student stu;
	struct Student *p; 
	p=&stu;	
	stu.num=10101;	//对结构体的变量成员赋值
	strcpy(stu.name,"Micheal");//注意:不能写成stu.name="Micheal"; 使用头文件#include<string.h>
	stu.sex='M';
	stu.score=89.5;
	//输出结构体(3种方式)
	printf("(num)%ld (name)%s (sex)%c (score)%5.1f \n" , stu.num,stu.name,stu.sex,stu.score);
	printf("(num)%ld (name)%s (sex)%c (score)%5.1f \n" , (*p).num,(*p).name,(*p).sex,(*p).score);
	printf("(num)%ld (name)%s (sex)%c (score)%5.1f \n\n" , p->num,p->name,p->sex,p->score);
	
	//2.指向结构体数组的指针
	struct Student stu1[3]={{1101,"Martin",'M',23,87.6f,"China"},{1102,"Tom",'M',16,92.3f,"America"},{1103,"Susan",'F',35,78.4f,"India"}};
	struct Student *p1;
	for(p1=stu1;p1<stu1+3;p1++){//注意使用方法
		printf("(num)%ld (name)%s (sex)%c (score)%5.1f \n" , p1->num,p1->name,p1->sex,p1->score);
	}
}
代码说明:
  1. (*p).num 表示p指向的结构体变量中的成员num。注意: *p 两侧的括号不能省,因为成员运算符 “ . ” 优先于“ * ”运算符,*p.num 就等价于 *(p.num);
  2. 如果p指向一个结构体变量stu,以下3种用法等价:
    ① stu.成员名(如:stu.num);
    ② (*p).成员名(如:(*p).num);
    ③ p->成员名(如:p->num);
  3. 对结构体成员变量:char name[20]; 的操作
    ①如果需要输入结构体变量的值的时候,请注意:
    对stu.name的输入方式为:scanf("%s",stu.name);//而不是scanf("%s",&stu.name);
    原因:name是数组名,本身就代表地址;
    ②如果要对结构体成员变量赋值时,请注意:
    对stu.name的赋值方式为:strcpy(stu.name,“Micheal”);//而不是 stu.name = “Micheal”;且注意添加头文件 #include<string.h>
运行结果

在这里插入图片描述

结构体和函数之间的参数使用(重点+难点)

  1. 结构体变量成员 作实参(例如:stu[1].num):属于“值传递”方式,注意实参和形参的类型保持一致。
  2. 结构体变量作实参(例如:stu):属于“值传递”方式,形参必须是与实参同类型的结构体变量。
    缺点:①这种传递方式在空间和时间上开销比较大;②在被调用函数期间改变了形参,并不能改变主函数中的实参值。
  3. 指向结构体变量(或数组元素)的指针作实参,将结构体变量(或数组元素)的地址传给形参。
案例

有n个结构体变量,内含学生学号、姓名和3门课程的成绩。要求输出平均成绩最高的学生信息(包括学号、姓名、3门课成绩和平均成绩)。

程序实现
#include<stdio.h>
#include<string.h>
#define N 3

//定义结构体
struct Student{
	long num;//学号为整型
	char name[20];//姓名为字符串
	float score[3];//成绩为实型
	float  aver;//平均成绩
};	//注意最后有一个分号

int main(){
	//函数声明
	void input(struct Student stu[]);//输入信息
	struct Student max(struct Student stu[]);//寻找平均成绩最高
	void print(struct Student stu);//输出信息

	struct Student stu[N];//定义结构体数组
	struct Student *p=stu;//定义结构体指针

	struct Student max_stu;//定义结构体变量
	input(p);
	max_stu=max(p);
	print(max_stu);

	return 0;
}

void input(struct Student stu[]){
	int i;
	printf("请输入各学生的信息(学号、姓名、三门课成绩):\n");
	for(i=0;i<N;i++){
		scanf("%ld %s",&stu[i].num,stu[i].name);//注意不能写成&stu[i].name,因为name是数组名,本身就代表地址
		for(int j=0;j<3;j++){//依次输入3门课的成绩
			scanf("%f",&stu[i].score[j]);
		}
		stu[i].aver = ( stu[i].score[0] + stu[i].score[1] + stu[i].score[2] )/3;//求平均值
	}
}

struct Student max(struct Student stu[]){
	int i,m=0;//m用来存放成绩最高的学生在数组中的序号
	for(i=1;i<N;i++){
		if(stu[i].aver>stu[m].aver){
			m=i;
		}
	}
	return stu[m];
}

void print(struct Student stu){
	printf("\n最高学生的成绩为:\n");
	printf("学号:%ld ,姓名:%s ,三门课成绩:%5.1f、%5.1f、%5.1f ,平均成绩:%6.2f \n",
		stu.num,stu.name,stu.score[0],stu.score[1],stu.score[2],stu.aver);
}

代码说明:

以上三个函数的调用情况各不相同:

  • 调用 input 函数时,实参是指针变量p,形参是结构体数组,传递的是结构体元素的地址,函数无返回值。
  • 调用 max 函数时,实参是指针变量p,形参是结构体数组,传递的是结构体元素的地址,函数的返回值是结构体类型数据。
  • 调用 print 函数时,实参是结构体变量(结构体数组元素),形参是结构体变量,传递的是结构体变量中各成员的值(“值传递”),函数无返回值。
运行结果:

在这里插入图片描述

案例2

有n个学生,每个学生的数据包括学号、姓名、3门课的成绩,从键盘上输入n个学生数据,要求输出3门课的总平均成绩,以及最高分的学生的数据(包括学号、姓名、3门课程成绩、平均分数)。

程序实现
#include<stdio.h>

#define N 3

struct Student{
	long id;
	char name[10];
	float score[3];
	float aver;
};

void input(struct Student stu[]);
void func(struct Student stu[],float (*p)[2]);

int main(){
	struct Student stu[N];
	struct Student *p=stu;
	float lessons[3][2];//二维数组{{该门课程的平均成绩,最高分学生的序号},{},{}}
	input(p);
	func(p,lessons);
	for(int i=0;i<3;i++){
		printf("第%d门课程的平均分为:%8.3f ,最高分的学生数据为:\n",i+1,lessons[i][0]);
		struct Student max_stu=stu[(int)lessons[i][1]];
		printf("学号:%ld ,姓名:%s ,三门课的成绩:%5.2f、%5.2f、%5.2f ,平均分:%f \n\n",
			max_stu.id,max_stu.name,max_stu.score[0],max_stu.score[1],max_stu.score[2],max_stu.aver);
	}
	return 0;
}

void input(struct Student stu[]){
	int i;
	printf("请输入学生信息(学号、姓名、3门课的成绩):\n");
	for(i=0;i<N;i++){
		scanf("%ld %s",&stu[i].id,stu[i].name);
		for(int j=0;j<3;j++)
			scanf("%f",&stu[i].score[j]);
		stu[i].aver=(stu[i].score[0]+stu[i].score[1]+stu[i].score[2])/3;
	}
}

void func(struct Student stu[],float (*p)[2]){
	int i,j,max_student;//max_student用来存放成绩最高的学生在数组中的序号
	for(i=0;i<3;i++){//3门课程
		max_student=0;

		*(*(p+i)+0)=0;//注意:初始化语句不能少;否则结果出于意料(本人在编程时,因为这个错误,耗了很久)

		for(j=0;j<N;j++){//N个学生
			*(*(p+i)+0)+=stu[j].score[i];//累加所有学生的该课程成绩
			if(stu[j].score[i]>stu[max_student].score[i])
				max_student=j;
		}
		*(*(p+i)+0)/=N;
		*(*(p+i)+1)=(float)max_student;
	}
}
代码说明:
  • 第46行代码: *( *(p+i)+0)=0; 的初始化语句不能少,否则结果可能会出乎意料。
运行结果:

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_42887760/article/details/84076506