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;
}