结构体中需要注意的几件事

1、题目名称:复数运算

题目描述:复数可以写成A+Bi的常规形式,其中A是实部,B是虚部,i是虚数单位,满足i^2=-1。

编写程序,分别计算两个复数的和、差、积。

输入:在一行中依次给出两个复数的实部和虚部,数字间以一个西文空格分隔。

输出:一行中按照A+Bi的格式输出两虚数的和、差、积,实部和虚部均保留2位小数;

如果B是负数,则应该写成A-|B|i的形式;如果B是零则不输出虚部;结果间以4个西文空格间隔。

样例1:

输入: 2.3 3.5 5.2 0.4
输出: 7.50+3.90i -2.90+3.10i 10.56+19.12i
样例2:

输入: 3.3 4.5 3.3 -4.5
输出: 6.60 0.00+9.00i 31.14

#include <stdio.h>
typedef struct {
 double real_part,imag_part;
}type;

void add(type x,type y);
void sub(type x,type y);
void mul(type x,type y);

int main()
{

 type a,b;

 scanf("%lf%lf%lf%lf",&a.real_part,&a.imag_part,&b.real_part,&b.imag_part);
 
 add(a,b);
 sub(a,b);
 mul(a,b);

 return 0;

}
void add(type x,type y){

 double i,j;

 i=x.real_part+y.real_part;

 j=x.imag_part+y.imag_part;

if(j>0) printf("%.2f+%.2fi    ",i,j);

else if(j<0) printf("%.2f-%.2fi    ",i,-j);

else if(j==0) printf("%.2f    ",i);

}

void sub(type x,type y){

 double i,j;

 i=x.real_part-y.real_part;

 j=x.imag_part-y.imag_part;

if(j>0) printf("%.2f+%.2fi    ",i,j);

else if(j<0) printf("%.2f-%.2fi    ",i,-j);

else if(j==0) printf("%.2f    ",i);

}

void mul(type x,type y){

 double i,j;

 i=x.real_part*y.real_part-x.imag_part*y.imag_part;

 j=x.real_part*y.imag_part+x.imag_part*y.real_part;

if(j>0) printf("%.2f+%.2fi",i,j);

else if(j<0) printf("%.2f-%.2fi",i,-j);

else if(j==0) printf("%.2f",i);
}

结构体的题目往往在输入数据的时候都是用访问的形式,(如a.real_part,b.imag_part等)而不是直接输入某个值。同时设计的函数的形参也往往都是结构体类型的,所以在传值的时候要记得传入结构体。在设计的函数内部进行的操作/运算通常是结构体成分访问的形式

2、题目内容:定义一个学生结构体,包括学生的姓名和一门课程成绩。实现用户从键盘输入n名学生的所有信息(最多不超过200人),输出所有不及格的学生姓名和成绩。

输入:依次输入n(正整数),姓名(不超过19个字符的字符串),成绩(正整数)。

输出:所有不及格的学生姓名和成绩(相邻数据用1个空格隔开,每个学生信息占用一行)。

样例1:
输入:
3
zhang 58
wang 72
zhao 34
输出:
zhang 58
zhao 34

#include <stdio.h>
struct {
	char name[19];
	int grade;
}ty_list[200];
int main(){
	int n,i;
	scanf("%d",&n);
	for(i=0;i<n;i++){
		scanf("%s%d",&ty_list[i].name,&ty_list[i].grade); 
	}
	for(i=0;i<n;i++){
		if(ty_list[i].grade<60)printf("%s %d\n",ty_list[i].name,ty_list[i].grade);
	}
	return 0;
}

注:以上代码摘自用户“焰与光”。
注意:
1.在读入每个学生名字的时候,不能使用gets 而应该用scanf(“%s”)。
这是因为gets 会把空格也读进去,所以一般我们在逐一地输入某字符串时(往往需要循环读入),都使用scanf(“%s”).而当题目只要求读入一串长字符时,则考虑使用gets.
2.本题的结构题变量和结构体的内部成分都是数组。
学习用结构体数组访问其数组成分的手法。
3.另外,在定义结构体类型的时候,c语言不推荐使用标签
直接 struct { … };或typedef {…}…;
struct 后面不加标签。否则的话标签名容易与变量名/类型名混淆。
然而,如果是c++的话则必须使用标签!否则系统会提示warning
4.在输出一个结构体的时候,可以采用自定义的输出函数,比如自定义一个void out(type m)函数(其中type是结构体类型),需要传入一个结构体,然后在out 函数内表达输出的格式即可。
5. 如果要对学生的成绩进行排序,如:
对每个测试用例输出 2 行,第 1 行是成绩最高学生的姓名和学号,第 2 行是成绩最低学生的姓名和学号

输入:
3
Joe Math990112 89
Mike CS991301 100
Mary EE990830 95
输出:
Mike CS991301
Joe Math990112

如果将代码写成这样的形式则不可:

for(int j=0;j<n;j++){
	if(stu[j].score==a[n-1])printf("%s %s\n",stu[j].name,stu[j].number);
	if(stu[j].score==a[0])printf("%s %s\n",stu[j].name,stu[j].number);
	}

因为在一遍遍历循环时,如果成绩不满足第一个条件(即数组中的最大值),会自动进行第二步操作(输出数组中的最小值),不能达到分别输出最大值和最小值的问题。
所以,为了达到先输入最大值,再输入最小值的目的,分别使用两次循环进行遍历。
代码如下:

for(int j=0;j<n;j++){
		if(stu[j].score==a[n-1])printf("%s %s\n",stu[j].name,stu[j].number);
	}
	for(int j=0;j<n;j++){
		if(stu[j].score==a[0])printf("%s %s",stu[j].name,stu[j].number);
	}

注意:如果本题改成要求输入一个学生的多名成绩:
参见以下代码:
(注意学习结构体中整型数组的输入

#include <stdio.h>
#include <stdlib.h>
typedef struct {
	char no[10];
	char name[50];
	int scores[6];
	double avg;	
}STU;
int main()
{
	int i,j,n;
	scanf("%d",&n);
	STU s[n];

	for(i=0;i<n;i++){
		scanf("%s%s",&s[i].no,&s[i].name);
		s[i].avg=0;
		for(j=0;j<6;j++){
			scanf("%d",&s[i].scores[j]);
			s[i].avg+=s[i].scores[j];
		}
		s[i].avg/=3;
	}
	for(i=0;i<n;i++){
		printf("%s %s %.1f\n",s[i].no,s[i].name,s[i].avg);
	}
	return 0; 
}

结构体赋值操作中的一个小技巧:

string nameSeed = "ABCDE";
for (int i = 0; i < len; i++){
	tArray[i].tName = "teacher_";
	tArray[i].tName += nameSeed[i]; 
}

结构体指针
(以下代码涵盖了c++中结构体指针的基本知识点)

#include <iostream>
#include <string>
using namespace std;
struct student{
	string name;
	int score;
	int num;
};
int main()
{
	
	student *stu;//可以不加struct,直接用标签来定义结构体指针。
	cin >> stu->name >> stu->num >> stu->score;
	cout << stu->name << stu->num << stu->score <<endl;
	return 0;
}

结构体数组做形参传入

struct stu a[3]={......};
len = sizeof(a)/sizeof(a[0]);
函数原型: void bubbleSort(struct stu a[],len);

结构体变量的交换

struct stu temp = a[i];
a[i] = a[i+1];
a[i+1] = temp;
需要注意的是,这里的临时变量temp也是结构体类型。 

结构体嵌套结构体
含义:结构体中的成员可以是另一个结构体
(以下代码涵盖了c++中结构体嵌套的基本知识点)

#include <iostream>
#include <string>
using namespace std;
struct student{
	string name;
	int age;
	int score;
};

struct teacher{
	int id;
	string name;
	int age;
	struct student stu;
};

注意struct student 的声明需在teacher之前,因为在teacher 的声明中调用了student。
第三次实验考:

#include <stdio.h>
#include <stdlib.h>
#define SIZE 50
#define N 20

struct StuInfo
{
    int No;//学号
    char Name[SIZE];//姓名
    int Mooc1;//大学慕课成绩,满分100分
    int Mooc2;//超星成绩,满分100分
    int Experiments;//实验机考成绩,满分100分
    int FinalExam;//期末机考成绩,满分100分
    double Score;//根据评分标准进行计算,结果保留2位小数
};

void InputStuInfo(struct StuInfo StuArr[],int n)//输入学生信息
{
    int i;
    for(i=0;i<n;i++)
        scanf("%d%s%d%d%d%d",
              &StuArr[i].No,
              StuArr[i].Name,
              &StuArr[i].Mooc1,
              &StuArr[i].Mooc2,
              &StuArr[i].Experiments,
              &StuArr[i].FinalExam);
}

struct StuInfo * CountStuInfo( /*---学生代码---*/struct StuInfo *a,int n,double *y/*---学生代码---*/ )//计算每位同学的总评成绩、找出总评成绩最高的同学、求班级平均分
{
    /*---学生代码---*/	*y = 0;
	int i,x;
	for (i = 0; i < n; i++)
	{
		a[i].Score = a[i].Mooc1*0.2 + a[i].Mooc2*0.2 + a[i].Experiments*0.4 + a[i].FinalExam*0.2;
	}
	int j = 0;
	for (i = 1;i < n;i++)
	{
		if (a[i].Score > a[j].Score)
			j = i;
	}
	for (i = 0; i < n; i++)
	{
		*y = *y + a[i].Score;
	}
	*y = *y / n;
	return &a[j];
/*---学生代码---*/
}

void PrintAll(struct StuInfo StuArr[],int n)
{
    int i;
    for(i=0;i<n;i++)
        printf("%d %s %.2lf\n",StuArr[i].No, StuArr[i].Name, StuArr[i].Score);
}
int main()
{
    struct StuInfo StuArr[N],*pStuTop1; //StuArr用于存储参与统计的学生信息
    int n;//参与统计的人数n
    double AveScore;//总评成绩的平均分,计算结果保留两位小数

    scanf("%d",&n);
    InputStuInfo(StuArr,n);//输入学生信息

    pStuTop1=CountStuInfo(  /*---学生代码---*/StuArr,n,&AveScore/*---学生代码---*/ );//函数调用

    printf("------Statistic------\n");
    PrintAll(StuArr,n);//按输入顺序依次输出每位学生的学号、姓名、总评成绩

    printf("Top1:%d %s %.2lf\n",pStuTop1->No,pStuTop1->Name,pStuTop1->Score);//输出总评成绩最高的那位同学的学号、姓名、总评成绩
    printf("AveScore:%.2lf",AveScore);//输出全班平均分
    return 0;
}

另解:
如果本题不限制函数原型的话,也可以通过二级指针作参数的方式带回给主调函数:

#include <stdio.h>
#include <stdlib.h>
#define SIZE 50
#define N 20

struct StuInfo
{
    int No;//学号
    char Name[SIZE];//姓名
    int Mooc1;//大学慕课成绩,满分100分
    int Mooc2;//超星成绩,满分100分
    int Experiments;//实验机考成绩,满分100分
    int FinalExam;//期末机考成绩,满分100分
    double Score;//根据评分标准进行计算,结果保留2位小数
};

void InputStuInfo(struct StuInfo StuArr[],int n)//输入学生信息
{
    int i;
    for(i=0;i<n;i++)
        scanf("%d%s%d%d%d%d",
              &StuArr[i].No,
              StuArr[i].Name,
              &StuArr[i].Mooc1,
              &StuArr[i].Mooc2,
              &StuArr[i].Experiments,
              &StuArr[i].FinalExam);
}

void CountStuInfo( struct StuInfo *head,double *aver,struct StuInfo **top,int n )//计算每位同学的总评成绩、找出总评成绩最高的同学、求班级平均分
{
    /*---学生代码---*/int m;
 	struct StuInfo *p=head;
    for(m=0;m<n;m++)
    {
    	head[m].Score=head[m].Mooc1*0.2+head[m].Mooc2*0.2+head[m].Experiments*0.4+head[m].FinalExam*0.2;
    	*aver+=head[m].Score;
	}
	*aver/=n;
	*top=head;
	for(m=0;m<n;m++)
	{
		if((**top).Score<head[m].Score)
		*top=&head[m];
	}	
}

void PrintAll(struct StuInfo StuArr[],int n)
{
    int i;
    for(i=0;i<n;i++)
        printf("%d %s %.2lf\n",StuArr[i].No, StuArr[i].Name, StuArr[i].Score);
}
int main()
{
    struct StuInfo StuArr[N],*pStuTop1; //StuArr用于存储参与统计的学生信息
    int n;//参与统计的人数n
    double AveScore;//总评成绩的平均分,计算结果保留两位小数

    scanf("%d",&n);
    InputStuInfo(StuArr,n);//输入学生信息

    CountStuInfo(StuArr,&AveScore,&pStuTop1,n );//函数调用

    printf("------Statistic------\n");
    PrintAll(StuArr,n);//按输入顺序依次输出每位学生的学号、姓名、总评成绩

    printf("Top1:%d %s %.2lf\n",pStuTop1->No,pStuTop1->Name,pStuTop1->Score);//输出总评成绩最高的那位同学的学号、姓名、总评成绩
    printf("AveScore:%.2lf",AveScore);//输出全班平均分
    return 0;
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值