怎么查题,怎么复制,在此就不再赘述了,下面有视频!

这绝对是全网最好的题库,尤其是编程题容不得一个符号错误,所以我整理了这个题库,好不好用自己品,细品!

练习1

第1 题

【描述】
在屏幕上显示“Hello World!”并换行。
【输入】
没有输入。
【输出】
Hello World!
【来源】
《程序设计基础——以C为例》第1章上机实验题1。
【参考答案】

#include <stdio.h>
int main(void)
{
   printf("Hello World!\n");
   return 0;
}

第2 题

【描述】
在屏幕上显示下列图案。
****
***
**

【输入】
没有输入。
【输出】
****
***
**

【来源】
《程序设计基础——以C为例》第1章上机实验题2。
【参考答案】

#include <stdio.h>
int main(void) 
{
    printf("****\n");
    printf("***\n");
    printf("**\n");
    printf("*\n");
    return 0;
}

第3 题

【描述】
编写程序,按照规定格式输出表格。
【输入】
没有输入。
【输出】
要求严格按照给出的格式输出下列表格:

------------------------------------
Province      Area(km2)   Pop.(10K)
------------------------------------
Anhui         139600.00   6461.00
Beijing        16410.54   1180.70
Chongqing      82400.00   3144.23
Shanghai        6340.50   1360.26
Zhejiang      101800.00   4894.00
------------------------------------

【参考答案】

#include <stdio.h>
int main(void) {
    printf("------------------------------------\n");
    printf("Province      Area(km2)   Pop.(10K)\n");
    printf("------------------------------------\n");
    printf("Anhui         139600.00   6461.00\n");
    printf("Beijing        16410.54   1180.70\n");
    printf("Chongqing      82400.00   3144.23\n");
    printf("Shanghai        6340.50   1360.26\n");
    printf("Zhejiang      101800.00   4894.00\n");
    printf("------------------------------------\n");
    return 0;
}

第4 题

【描述】
编写程序,在屏幕上显示表达式1+2+3+4+5+6+7+8+9+10的值。
【输入】
没有输入。
【输出】
显示表达式的值。
【参考答案】

#include <stdio.h>
int main(void) {
    printf("%d\n", 1+2+3+4+5+6+7+8+9+10);
    return 0;
}

第5 题

【描述】
计算圆柱体的体积。
假设PI为3.14159。
底面积area= PI × radius ×radius。
体积volume= area × length。
【输入】
输入圆柱体的半径和高。
【输出】
输出对应的圆柱体体积
【输入示例】
2.5 3.5
【输出示例】
68.722281
【提示】
程序中不要有任何用户友好性提示等的输出,只能严格按照题目中所规定的输出格式的要求来输出。可以运行自己的程序,用题目中的输入示例来输入,如果得到的输出和输出示例完全相同,一个字符也不多,一个字符也不少,那么这样的格式就是对的了。
【来源】
《程序设计基础——以C为例》第1章上机实验题3。

【参考答案】

#include <stdio.h>
#define PI 3.14159
int main(void) {
    double radius, length;
    double area, volume;
      scanf("%lf%lf", &radius, &length);
      area = PI * radius * radius;
    volume = area * length;
    printf("%f\n", volume);
      return 0;
}

练习2

第1 题

描述】
将摄氏温度转换为华氏温度。
转换公式为:

f表示华氏温度,c表示摄氏温度。
【输入】
输入一个摄氏温度。
【输出】
输出对应的华氏温度。
【输入示例】
100
【输出示例】
212.000000
【提示】
程序中不要有任何用户友好性提示等的输出,只能严格按照题目中所规定的输出格式的要求来输出。可以运行自己的程序,用题目中的输入示例来输入,如果得到的输出和输出示例完全相同,一个字符也不多,一个字符也不少,那么这样的格式就是对的了。
【来源】
《程序设计基础——以C为例》第2章上机实验题1。
【参考答案】

#include <stdio.h>
int main(void) {
      double c, f;
      scanf("%lf", &c);
      f = (9.0 / 5.0) * c + 32;
    printf("%f\n", f);
      return 0;
}

第2 题

【描述】
计算两个整数的和、差、积、商、余数。
【输入】
输入整数a和b。
【输出】
分行输出整数a和b的和、差、积、商、余数。
【输入示例】
5 3
【输出示例】
8
2
15
1
2
【提示】
程序中不要有任何用户友好性提示等的输出,只能严格按照题目中所规定的输出格式的要求来输出。可以运行自己的程序,用题目中的输入示例来输入,如果得到的输出和输出示例完全相同,一个字符也不多,一个字符也不少,那么这样的格式就是对的了。
【来源】
《程序设计基础——以C为例》第2章上机实验题2。
【参考答案】

#include <stdio.h>
int main(void) {
      int a, b;
      scanf("%d%d", &a, &b);
      printf("%d\n", (a + b));
      printf("%d\n", (a - b));
      printf("%d\n", (a * b));
      printf("%d\n", (a / b));
      printf("%d\n", (a % b));
      return 0;
}

第3 题

【描述】
判断两个整数之间的关系:大于、小于、等于、不等于。
【输入】
输入整数a和b。
【输出】
分行输出整数a和b之间的关系(若a大于b,输出1,否则输出0)。
【输入示例】
5 3
【输出示例】
1
0
0
1
【提示】
程序中不要有任何用户友好性提示等的输出,只能严格按照题目中所规定的输出格式的要求来输出。可以运行自己的程序,用题目中的输入示例来输入,如果得到的输出和输出示例完全相同,一个字符也不多,一个字符也不少,那么这样的格式就是对的了。
【来源】
《程序设计基础——以C为例》第2章上机实验题2强化练习。

【参考答案】

#include <stdio.h>
int main(void) {
      int a, b;
      scanf("%d%d", &a, &b);
      printf("%d\n", (a > b));
      printf("%d\n", (a < b));
      printf("%d\n", (a == b));
      printf("%d\n", (a != b));
      return 0;
}

第4 题

【描述】
计算两个整数的和、平均值、最小值和最大值。要求平均值保留2位小数,用条件运算符求最小值和最大值。
【输入】
输入整数a和b。
【输出】
分行输出整数a和b的和、平均值、最小值和最大值。
【输入示例】
5 3
【输出示例】
8
4.00
3
5
【来源】
《程序设计基础——以C为例》第2章上机实验题3。
【参考答案】

#include <stdio.h>
int main(void) {
    int a, b;
    int sum, min, max;
    double average;
    scanf("%d%d", &a, &b);
    sum = a + b;
    printf("%d\n", sum);
    average = (a + b) / 2.0;
    printf("%.2f\n", average);
    min = (a > b) ? b : a;
    printf("%d\n", min);
    max = (a > b) ? a : b;
    printf("%d\n", max);
    return 0;
}

第5 题

【描述】
交换a和b中的值。
【输入】
输入整数a和b。
【输出】
输出交换后的整数a和b。
【输入示例】
5 3
【输出示例】
3 5
【提示】
交换是指将两个变量的值进行互换。假设有整型变量a和b,交换变量a和b中的值,使得变量a存放变量b交换前的值,而变量b存放变量a交换前的值。
要实现交换,最基本、最通用的方法是中间变量法。基本思路是定义第三个变量t,用于暂时保存两个变量中的某一个变量的原值。实现代码如下:
t = a;
a = b;
b = t;
【来源】
《程序设计基础——以C为例》第2章上机实验题4。
【参考答案】

#include <stdio.h>
int main(void) {
    int a, b, t;
    scanf("%d%d", &a, &b);
    t = a;
    a = b;
    b = t;
    printf("%d %d\n", a, b);
    return 0;
}

第6 题

【描述】
将一个三位正整数(假设其个位数不为0)按逆序转换为新的整数后输出。例如,输入123,输出321。
【输入】
输入一个三位正整数。
【输出】
输出将该整数逆序后的新整数。
【输入示例】
123
【输出示例】
321
【提示】
数的各位分离是指将整数n的每一位数取出,在取数的过程中,反复运用“%”和“/”运算符,“n% 10”运算可以取出整数n的个位数,而“n/ 10”运算可以将整数n的十位数移至个位数、百位数移至十位数、……,反复运用这两个表达式就可以取出整数n的每一位数。
假设整数n为123,则:

a = n% 10;                                  /*a的值是3 */
b = (n/ 10) % 10;                           /*b的值是2 */
c = (n / 10 / 10) % 10;                     /*c的值是1 */
n = a* 100 + b * 10 + c;                    /*新的n值是321*/

【来源】
《程序设计基础——以C为例》第2章上机实验题5。
【参考答案】

#include <stdio.h>
int main(void) {
    int a, b, c, n;
    scanf("%d", &n);
    a = n % 10;
    b = (n / 10) % 10;
    c = (n / 10 / 10) % 10;
    n = a * 100 + b * 10 + c;
    printf("%d\n", n);
    return 0;
}

第7 题

【描述】
计算存款到期时的税前利息。计算公式如下:
interest = money(1+rate)year-money

【输入】
输入存款(money)、存期(year)和年利率(rate)。
【输出】
计算存款到期时的税前利息(interest),要求保留小数点后2位精度。
【输入示例】
10000
3
0.025
【输出示例】
768.91
【提示】
可以使用数学库中的pow函数。包含头文件<math.h>
【来源】
《程序设计基础——以C为例》第2章上机实验题7强化练习。
【参考答案】

#include <stdio.h>
#include <math.h>
int main(void) {
    int money, year;
    double rate, interest;
    scanf("%d", &money);
    scanf("%d", &year);
    scanf("%lf", &rate);
    interest = money * pow((1 + rate), year) - money;
    printf("%.2f\n", interest);
    return 0;
}

第8 题

【描述】
计算并输出分段函数f的值,要求保留小数点后2位精度。
分段函数的数学定义如下:

【输入】
输入整数x。
【输出】
输出分段函数f的值。
【输入示例】
10
【输出示例】
3.16
【提示】
可以使用条件运算符。可以使用数学库中的pow函数和sqrt函数。包含头文件<math.h>。
【来源】
《程序设计基础——以C为例》第2章上机实验题6。
【参考答案】

#include <stdio.h>
#include <math.h>
int main(void) {
    int x;
    double f;
    scanf("%d", &x);
    f = (x < 0) ? pow((x + 1), 2) + 2 * x + 1.0 / x : sqrt(x);
    printf("%.2f\n", f);
    return 0;
} 

第9 题

【描述】
输入一个整数a(a不为-1),求如下表达式的值,结果保留小数点后2位精度。

【输入】
输入一个整数a。
【输出】
输出表达式的值,结果保留小数点后2位精度。
【输入示例】
2
【输出示例】
2.26
【提示】
可以使用数学库中的cos函数和sqrt函数。包含头文件<math.h>。
【来源】
《程序设计基础——以C为例》第2章上机实验题8。
【参考答案】

#include <stdio.h>
#include <math.h>
#define PI 3.14159
int main(void) {
    int a;
    scanf("%d", &a);
    printf("%.2f\n", (cos(50 * PI / 180) + sqrt(37.5)) / (a + 1));
    return 0;
}

第10 题

【描述】
将一个大写字母转换为小写字母。
【输入】
输入一个字母。
【输出】
输出对应的小写字母。注意:若输入的是小写字母,则直接输出。
【输入示例】
A
【输出示例】
a
【来源】
《程序设计基础——以C为例》第2章上机实验题10。
【参考答案】

#include <stdio.h>
#include <ctype.h>
int main(void) {
    int lowercase, uppercase;
    uppercase = getchar();
    lowercase = isupper(uppercase) ? tolower(uppercase) : uppercase;
    printf("%c\n", lowercase);
    return 0;
}

练习3

第1 题

【描述】
输入一个四位正整数,将该整数每一位上的数字加9,然后除以10取余,作为该位上的新数字,最后将千位和十位上的数字互换,百位和个位上的数字互换,组成变换后的新四位正整数并输出。题目保证转换后的数的千位不会为0。
【输入】
输入一个四位正整数。
【输出】
输出变换后的新四位正整数。
【输入示例】
1257
【输出示例】
4601
【来源】
《程序设计基础——以C为例》第2章上机实验题5强化练习。
【参考答案】

#include <stdio.h>
int main(void) {
    int n;
    scanf("%d", &n);
    int a = n % 10;                    /* 个位 */
    int b = (n / 10) % 10;        /* 十位 */
    int c = (n / 10 / 10) % 10;        /* 百位 */
    int d = (n / 10 / 10 / 10) % 10;    /* 千位 */
    a = (a + 9) % 10;                  /* 加9并除以10取余 */
    b = (b + 9) % 10;
    c = (c + 9) % 10;
    d = (d + 9) % 10;
    n = b * 1000 + a * 100 + d * 10 + c;
    printf("%d\n", n);
    return 0;
}

第2 题

【描述】
输入一个整数,检查它是否能同时被2和3整除,是否被2或3整除,是否被2或3整除且只被其一整除。
【输入】
输入一个整数。
【输出】
分行输出该整数是否能同时被2和3整除,是否被2或3整除,是否被2或3整除且只被其一整除。见输出示例。
【输入示例】
18
【输出示例】
18 divisible by 2 and 3? 1
18 divisible by 2 or 3? 1
18 divisible by 2 or 3, but not both? 0
【来源】
《程序设计基础——以C为例》第3章上机实验题1。
【参考答案】

#include <stdio.h>
int main() {
    int n;
    scanf("%d", &n);
    printf("%d%s%d\n", n, " divisible by 2 and 3? ", 
           (n % 2 == 0 && n % 3 == 0));
    printf("%d%s%d\n", n, " divisible by 2 or 3? ", 
           (n % 2 == 0 || n % 3 == 0));
    printf("%d%s%d\n", n, " divisible by 2 or 3, but not both? ", 
          ((n % 2 == 0 || n % 3 == 0) && !(n % 2 == 0 && n % 3 == 0)));
    return 0;
}

第3 题

【描述】
晶晶的朋友贝贝约晶晶下周一起去看展览,但晶晶每周的1、3、5必须上课,请帮晶晶判断她能否接受贝贝的邀请,如果能输出YES;如果不能则输出NO。
【输入】
输入贝贝邀请晶晶去看展览的日期,用数字1到7表示从星期一到星期日。
【输出】
如果晶晶可以接受贝贝的邀请,输出YES,否则,输出NO。注意YES和NO都大写!
【输入示例】
2
【输出示例】
YES
【参考答案】

#include <stdio.h>
int main(void) {
    int day;
    scanf("%d", &day);
    if(day != 1 && day != 3 && day != 5)
        printf("YES\n");
    else
        printf("NO\n");
    return 0;
}

第4 题

【描述】
输入a、b和c,若它们能构成三角形,则输出三角形周长,否则输出“Invalid”。
【输入】
输入a、b和c。
【输出】
输出三角形周长或“Invalid”。
【输入示例】
1 2 3
【输出示例】
Invalid
【参考答案】

#include <stdio.h>
int main(void) {
    double a, b, c;
    scanf("%lf%lf%lf", &a, &b, &c);
    if((a + b > c) && (a + c > b) && (b + c > a))
        printf("%lf\n", (a + b + c));
    else
        printf("Invalid");
    return 0;
}
            

第5 题

【描述】
输入一个数,输出分段函数的值,结果保留2位小数。
分段函数的数学定义如下:

【输入】
输入x。
【输出】
输出分段函数f的值,结果保留2位小数。
【输入示例】
2.5
【输出示例】
1.58
【来源】
《程序设计基础——以C为例》第3章上机实验题2。
【参考答案】

#include <stdio.h>
#include <math.h>
int main(void) {
    double x, y;
    scanf("%lf", &x);
    if(x < 0)
        y = x * x;                 /* 满足x<0 */
    else if(x < 9)
        y = sqrt(x);               /* 不满足x<0,但满足x<9,即满足0≤x<9 */
    else
        y = x - 6;                 /* 不满足x<0,也不满足x<9,即满足x≥9 */
    printf("%.2lf\n", y);
    return 0;
}

第6 题

【描述】
假设铁路托运行李,规定每张客票托运费的计算方法是:
(1)行李重量不超过50千克时,每千克0.25元;
(2)超过50千克而不超过100千克时,其超过部分每千克0.35元;
(3)超过100千克时,其超过部分每千克0.45元。
输入行李重量,计算并输出所需的运费,结果保留2位小数。
【输入】
输入行李重量(单位千克)。
【输出】
输出所需的运费。
【输入示例】
75
【输出示例】
21.25
【来源】
《程序设计基础——以C为例》第3章上机实验题3强化练习。
【参考答案】

#include <stdio.h>
int main(void) {
    double weight, freight;
    scanf("%lf", &weight);
    if(weight <= 50)
        freight = weight * 0.25;
    else if(weight <= 100)
        freight = 50 * 0.25 + (weight - 50) * 0.35;
    else
        freight = 50 * 0.25 + 50 * 0.35 + (weight - 100) * 0.45;
    printf("%.2f\n", freight);
    return 0;
}

第7 题

【描述】
求一元二次方程

的根,系数a、b、c为浮点数。
【输入】
输入a、b和c。
【输出】
若无穷解,则输出:Infinitely solution。
若无解,则输出:No solution。
若是一个实根,则输出格式为:x=…,数字、符号之间没有空格,结果保留2位小数。
若两个实根相等,则输出格式为:x1=x2=...,数字、符号之间没有空格,结果保留2位小数。
若是两个实根,则输出格式为:x1=...;x2=...,数字、符号之间没有空格,结果保留2位小数。
若是虚根,则输出:Imaginary root。
【输入示例】
2.1 8.9 3.5
【输出示例】
x1=-0.44;x2=-3.80
【提示】
求平方根可以使用数学库中的sqrt函数,求绝对值可以使用数学库中的fabs函数。方程的根以及其它中间变量用double类型变量表示。
【来源】
《程序设计基础——以C为例》第3章上机实验题4强化练习。
【参考答案】

#include <stdio.h>
#include <math.h>
#define EPSILON 1e-6
int main(void) {
    double a, b, c;
    double delta, real_part, imaginary_part;
       scanf("%lf%lf%lf", &a, &b, &c);
    if(fabs(a) <= EPSILON && fabs(b) <= EPSILON && fabs(c) <= EPSILON)
        printf("Infinitely solution\n");
    else if(fabs(a) <= EPSILON && fabs(b) <= EPSILON)
        printf("No solution\n");
    else if(fabs(a) <= EPSILON)
        printf("x=%.2f\n", -c / b);
    else {
        real_part = -b / (2 * a);
        delta = b * b - 4 * a * c;
        imaginary_part = sqrt(fabs(delta)) / (2 * a);
        if(fabs(delta) <= EPSILON)
            printf("x1=x2=%.2f\n", real_part);
        else if(delta > EPSILON) {
            printf("x1=%.2f;x2=%.2f\n", real_part+imaginary_part, real_part-imaginary_part);
        }
        else {
            printf("Imaginary root\n");
        }
    }
    return 0;
}

第8 题

【描述】
你买了一箱n个苹果,很不幸的是买完时箱子里混进了一条虫子。虫子每x小时能吃掉一个苹果,假设虫子在吃完一个苹果之前不会吃另一个,那么经过y小时你还有多少个完整的苹果?
【输入】
输入n,x和y(均为整数)。
【输出】
输出完整的苹果数(整数)。
【输入示例】
10 4 9
【输出示例】
7
【参考答案】

#include <stdio.h>
int main(void) {
    int n, x, y, eaten;
    scanf("%d%d%d", &n, &x, &y);
    eaten = y / x;
    if(eaten >= n)
        eaten = n;
    else if(y % x != 0)
        ++eaten;
    printf("%d\n", (n - eaten));
    return 0;
}

第9 题

【描述】
输入学生的考试成绩(0~100),将学生的成绩划分等级并输出。学生的成绩可分为5个等级:90~100为A级,80~89为B级,70~79为C级,60~69为D级,0~59为E级。要求用switch语句。
【输入】
输入学生的考试成绩(0~100)。
【输出】
输出等级。
【输入示例】
91
【输出示例】
A
【提示】
假设学生的成绩为score,则score/10的一个值就代表了10种情况,例如score/10为7时,就代表成绩70~79的情况。
【来源】
《程序设计基础——以C为例》第3章上机实验题5。
【参考答案】

#include <stdio.h>
int main(void) {
    int score;
    char grade;
    scanf("%d", &score);
    score = score / 10;
    switch (score) {
        case 0:
        case 1:
        case 2:
        case 3:
        case 4:
        case 5: grade = 'E'; break;
        case 6: grade = 'D'; break;
        case 7: grade = 'C'; break;
        case 8: grade = 'B'; break;
        case 9:
        case 10: grade = 'A'; break;
    }
    printf("%c\n", grade);
    return 0;
}

第10 题

【描述】
某校学生成绩的绩点计算方法如下(百分制折合为绩点):
(A)90~100分,折合4.0~5.0绩点。
(B)80~89分,折合3.0~3.9绩点。
(C)70~79分,折合2.0~2.9绩点。
(D)60~69分,折合1.0~1.9绩点。
(E)59分及其以下为不及格。
【输入】
输入一个整数表示学生的成绩(0~100)。
【输出】
如果输入的学生成绩不合法,则输出“Invalid”。
如果输入的学生成绩为不及格,则输出“Failed”。
否则,输出成绩对应的绩点,结果保留1位小数。
【输入示例】
74
【输出示例】
2.4
【参考答案】

#include <stdio.h>
int main(void) {
    int score;
    scanf("%d", &score);
    if(score < 0 || score > 100)
    printf("Invalid\n");
    else if(score >= 0 && score < 60)
        printf("Failed\n");
    else
    printf("%.1f", (1.0 + (score - 60) * 0.1));
    return 0;
}

练习4

第1 题

【描述】
计算如下式子:
1+2+3+…+n
前n项之和。
【输入】
输入一个正整数n。
【输出】
输出数列前n项的和。
【输入示例】
100
【输出示例】
5050
【来源】
《程序设计基础——以C为例》第3章上机实验题6。
【参考答案】

#include <stdio.h>
int main(void) {
    int n, sum, i;
    scanf("%d", &n);
    sum = 0;
    for(i = 1; i <= n; ++i)
        sum += i;
    printf("%d\n", sum);
    return 0;
}

第2 题

【描述】
计算如下式子:

前n项之和,结果保留3位小数。
【输入】
输入一个正整数n。
【输出】
输出数列前n项的和,结果保留3位小数。
【输入示例】
10
【输出示例】
2.133
【来源】
《程序设计基础——以C为例》第3章上机实验题6强化练习。
【参考答案】

#include <stdio.h>
int main(void) {
    int i, n;
    double sum = 0;
    scanf("%d", &n);
    for(i = 1; i <= n; ++i)
        sum += 1.0 / (2 * i - 1);
    printf("%.3f\n", sum);
    return 0;
}

第3 题

【描述】
计算如下式子:

的值,计算到最后一项的值小于0.0000001时为止。
【输入】
没有输入。
【输出】
输出式子的值,计算到最后一项的值小于0.0000001时为止。
【提示】
这是一个累加问题,因此需要一个存放累加和的变量,其初始值为0;
每个子项的绝对值可表示为:,这里要注意正负交替的情况;
当某一子项的绝对值小于0.0000001时终止计算。
【来源】
《程序设计基础——以C为例》第3章上机实验题8。
【参考答案】

#include <stdio.h>
#include <math.h>
#define EPSILON 1e-7
int main(void) {
    int n = 1;
    int flag = 1;
    double item = 1;
    double sum = 0;
    while(fabs(item) >= EPSILON) {
        sum += item;
        flag = -flag;
        ++n;
        item = 1.0  * flag / (3 * n - 2);
    }
    printf("%f\n", sum);
    return 0;
}

第4 题

【描述】
计算如下式子:

的值,计算到最后一项的值小于0.000001时为止。
【输入】
没有输入。
【输出】
输出式子的值,计算到最后一项的值小于0.000001时为止。
【来源】
《程序设计基础——以C为例》第3章上机实验题8强化练习。
【参考答案】

#include <stdio.h>
#define EPSILON 1e-6
int main(void) {
    int i;
    double fact, item, e;
    i = 1;
    fact = 1;
    item = 1;
    e = 0;
    while(item >= EPSILON) {
        e += item;
        fact *= i;
        item = 1 / fact;
        ++i;
    }
    printf("%f\n", e);
    return 0;
}

第5 题

【描述】
输入若干个整数,如果输入0,输入即终止。判定读入的整数中有多少个正整数、多少个负整数,并计算这些整数的总和和平均值(0不计算在内)。平均值结果保留2位小数。
【输入】
输入若干个整数,如果输入0,输入即终止。
【输出】
分行输出这些整数中的正整数个数、负整数个数、总和、平均值(0不计算在内)。
若只输入0,则输出:No input。
【输入示例】
-1 -2 -3 -4 -5 6 7 8 9 0
【输出示例】
4
5
15
1.67
【来源】
《程序设计基础——以C为例》第3章上机实验题9。
【参考答案】

#include <stdio.h>
int main(void) {
    int countPositive = 0;
    int countNegative = 0;
    int count = 0;
    int sum = 0;
    int number;
    do {
        scanf("%d", &number);
        if (number > 0)
            ++countPositive;
        else if (number < 0)
            ++countNegative;
        sum += number;
        ++count;
    } while (number != 0);
    --count;
    if (count == 0)
        printf("No input");
    else {
        printf("%d\n", countPositive);
        printf("%d\n", countNegative);
        printf("%d\n", sum);
        printf("%.2f\n", (sum * 1.0 / count));
    }
    return 0;
}

第6 题

【描述】
输入若干个字符,分别统计其中英文字母、数字字符和其他字符的个数。
【输入】
输入若干个字符。
【输出】
分行输出这些字符中的英文字母个数、数字字符个数、其他字符个数。
【输入示例】
Reold 123?
【输出示例】
5
3
2
【来源】
《程序设计基础——以C为例》第3章上机实验题9强化练习。

【参考答案】

#include <stdio.h>
#include <ctype.h>
int main(void) {
    int letter, digit, other;
    char ch;
    letter = digit = other = 0;
    while((ch = getchar()) != '\n') {
       if(isalpha(ch))
           ++letter;
       else if(isdigit(ch))
           ++digit;
       else
           ++other;
   }
   printf("%d\n", letter);
   printf("%d\n", digit);
   printf("%d\n", other);
   return 0;
}

第7 题

【描述】
计算如下式子:
7
的值。
例如a为2,n为5,则式子的值为24690(2+22+222+2222+22222)。
【输入】
输入a和n。
【输出】
输出式子的值。
【输入示例】
2 5
【输出示例】
24690
【来源】
《程序设计基础——以C为例》第3章上机实验题7。
【参考答案】

#include <stdio.h>
int main(void) {
    int i, a, n, item, sum;
    scanf("%d%d", &a, &n);
    item = a;
    sum = a;
    for(i = 2; i <= n; ++i) {
        item = item * 10 + a;
        sum += item;
    }
    printf("%d\n", sum);
    return 0;
}

第8 题

【描述】
计算如下式子:
1+(1+2)+(1+2+3)+(1+2+3+4)+…
的前n项之和。
【输入】
输入一个正整数n。
【输出】
输出数列前n项的和。
【输入示例】
3
【输出示例】
10
【来源】
《程序设计基础——以C为例》第3章上机实验题7强化练习。

【参考答案】

#include <stdio.h>
int main(void) {
    int i, j, n, sum, subitem;
    scanf("%d", &n);
    sum = 0;
    for(i = 1; i <= n; ++i) {
        subitem = 0;
        for(j = 1; j <= i; ++j)
            subitem += j;
        sum += subitem;
    }
    printf("%d\n", sum);
    return 0;
}

第9 题

【描述】
搬石头:有100块石头,1只大象一次能扛19块,1只老虎一次能抗12块,4只松鼠一起一次能扛1块。有15只动物(大象、老虎和松鼠)一次能将这100块扛完。求出这三种动物各有多少只。
【输入】
没有输入。
【输出】
输出大象、老虎和松鼠各有多少只。
【输出示例】
A,B,C
A、B、C分别表示大象、老虎、松鼠的个数。
【来源】
《程序设计基础——以C为例》第3章上机实验题10强化练习。

【参考答案】

#include <stdio.h>
int main(void) {
    int elephant, tiger, squirrel;
    for(elephant = 1; elephant <= 5; ++elephant) {
        for(tiger = 1; tiger <= 8; ++tiger) {
            squirrel = 15 - elephant - tiger;
            if((elephant * 19 + tiger * 12 + squirrel * 0.25 == 100) && (squirrel % 4 == 0))
                printf("%d,%d,%d\n", elephant, tiger, squirrel);
         }
    }
    return 0;
}

第10 题

【描述】
给定一个十进制正整数,求其对应的二进制数中1的个数。
【输入】
第一个正整数表示有n(n> 0)个测试数据,其后n行是对应的测试数据,每行为一个正整数。
【输出】
分行输出n个正整数对应的二进制数中1的个数。
【输入示例】
4
2
100
1000
66
【输出示例】
1
3
6
2
【参考答案】

#include <stdio.h>
int main(void) {
    int i, n;
    int value, count_1, remainder;
    scanf("%d", &n);
    for(i = 0; i < n; ++i) {
        scanf("%d", &value);
        count_1 = 0;
        while(value) {
            remainder = value % 2;
            if(remainder == 1)
                ++count_1;
            value = value / 2;
        }
        printf("%d\n", count_1);
    }
    return 0;
}

练习5

第1 题

【描述】
求三个整数的最大值。要求定义和调用函数:int max(intnum1, int num2, int num3),它返回num1、num2和num3中的最大值。
【输入】
输入三个整数,整数之间以空格间隔。
【输出】
输出三个整数的最大值。
【输入示例】
3 4 5
【输出示例】
5
【来源】
《程序设计基础——以C为例》第4章上机实验题2。
【参考答案】

#include <stdio.h>
int max(int num1, int  num2, int num3);
int main(void) {
    int a, b, c;
    scanf("%d%d%d", &a, &b, &c);
    printf("%d\n", max(a, b, c));
    return 0;
}
int max(int num1, int  num2, int num3) {
    int result;
    result = num1;
    if(result < num2)
        result = num2;
    if(result < num3)
        result = num3;
    return result;
}

第2 题

【描述】
如果四边形四条边的长度分别为a、b、c、d,一对对角之和为2α,则求其面积的公式如下:

其中

要求定义和调用函数:double computeArea(doublea, double b, double c, double d, double alpha),该函数返回任意四边形的面积。
π值为3.14159。
【输入】
输入四边形的四条边a、b、c、d和一对对角之和2α(单位为度数)
【输出】
输出对应的任意四边形面积。
【输入示例】
3 4 5 5 145
【输出示例】
16.615057
【提示】
可以使用数学库中的cos函数,单位为弧度。包含头文件<math.h>。
【来源】
《程序设计基础——以C为例》第4章上机实验题1。
【参考答案】

#include <stdio.h>
#include <math.h>
#define PI 3.14159
double computeArea(double a, double b, double c, double d, double alpha);
int main(void) {
    double a, b, c, d, alpha;
    scanf("%lf%lf%lf%lf%lf", &a, &b, &c, &d, &alpha);
    alpha = alpha * PI / 360;
    printf("%f\n", computeArea(a, b, c, d, alpha));
    return 0;
}
double computeArea(double a, double b, double c, double d, double alpha) {
    double p, area;
    p = (a + b + c + d) * 0.5;
    area = sqrt((p - a) * ( p - b) * (p - c) * (p - d) - a * b * c * d * cos(alpha) * cos(alpha));
    return area;
}

第3 题

【描述】
求一个整数的逆序数。要求定义和调用函数:int reverse(int n),该函数返回一个整数的逆序数。
【输入】
输入一个整数。
【输出】
输出整数的逆序数。
【输入示例】
-123
【输出示例】
-321
【来源】
《程序设计基础——以C为例》第4章上机实验题3。
【参考答案】

#include <stdio.h>
int reverse(int n);
int main() {
    int n;
    scanf("%d", &n);
    printf("%d\n", reverse(n));
    return 0;
}
int reverse(int n) {
    int remainder, result = 0, flag = 1;
    if(n < 0) {
        n = -n;
        flag = -1;
    }
    while (n != 0) {
        remainder = n % 10;
        result = result * 10 + remainder;
        n = n / 10;
    }
    return flag * result;
}

第4 题

【描述】
求一个正整数各位数字之和。要求定义和调用函数:int sumDigits(int n),该函数返回一个正整数各位数字之和。
【输入】
输入一个正整数。
【输出】
输出该正整数各位数字之和。
【输入示例】
3456
【输出示例】
18
【参考答案】

#include <stdio.h>
int sumDigits(int n);
int main() {
    int n;
    scanf("%d", &n);
    printf("%d\n", sumDigits(n));
    return 0;
}
int sumDigits(int n) {
    int remainder, result = 0;
    while (n != 0) {
        remainder = n % 10;
        result += remainder;
        n = n / 10;
    }
    return result;
}

第5 题

【描述】
输入一个正整数,判断它是否是回文数。要求定义和调用函数:int isPalindrome(int n),如果n是回文数,该函数返回1,否则返回0。回文数是指正读和反读都相同的数。
【输入】
输入一个正整数。
【输出】
如果该正整数是回文数,输出true,否则输出false。
【输入示例】
616
【输出示例】
true
【来源】
《程序设计基础——以C为例》第4章实例学习。
【参考答案】

#include <stdio.h>
int isPalindrome(int n);
int main() {
    int n;
    scanf("%d", &n);
    printf(isPalindrome(n) ? "true" : "false");
    return 0;
}
int isPalindrome(int n) {
    int temp, remainder, result = 0;
    temp = n;
    while (temp != 0) {
        remainder = temp % 10;
        result = result * 10 + remainder;
        temp = temp / 10;
    }
    return (n == result);
}

第6 题

【描述】
如果一个素数可以写成的形式,其中p是一个正整数,那么该素数就称为梅森素数。
例如,p为2时,为3,3就是梅森素数。
注意:1不是素数。
要求定义和调用函数:int isPrime(int n),如果n是素数,该函数返回1,否则返回0。
【输入】
输入一个正整数n(0≤n≤31)。
【输出】
输出p≤n的梅森素数的个数。
【输入示例】
3
【输出示例】
2
【参考答案】

#include <stdio.h>
#include <math.h>
int isPrime(int n);
int main() {
    int p, n, count = 0;
    scanf("%d", &n);
    for(p = 1; p <= n; ++p) {
        if(isPrime(pow(2, p) - 1))
            ++count;
    }
    printf("%d\n", count);
    return 0;
}
int isPrime(int n) {
    int i, limit, flag = 1;
    if(n <= 1)
        flag = 0;
    else if(n == 2)
        flag = 1;
    else if(n % 2 == 0)
        flag = 0;
    else {
        limit = sqrt(n) + 1;
        for(i = 3; i <= limit; i += 2) {
            if(n % i == 0) {
                flag = 0;
                break;
            }
        }
    }
    return flag;
}

第7 题

【描述】
无暇素数emirp(英文素数prime的逆序)是这样一种素数:本身为素数,且其逆序数也是素数。例如,17是素数,其逆序数71也是,因此17和71是emirp。定义和调用函数:intisPrime(int n),判断n是否是素数,如果是素数,函数返回1,否则返回0;定义和调用函数:int reverse(int n),求n的逆序数,函数返回n的逆序数,如n为17,函数reverse(n)返回71。
输出前n个emirp,每行显示5个,并适当对齐。
【输入】
输入一个正整数n。
【输出】
输出前n个emirp,每行显示5个,每个宽度为5。
【输入示例】
10
【输出示例】

    2    3    5    7   11
   13   17   31   37   71

【提示】
对于整数i,如果isPrime(i)与isPrime(reverse(i))的返回值都是1,i即为无暇素数。
【来源】
《程序设计基础——以C为例》第4章上机实验题5。
【参考答案】

#include <stdio.h>
#include <math.h>
int isPrime(int n);
int reverse(int n);
int main(void) {
    int i, n, count = 0;
    scanf("%d", &n);
    for(i = 2; count < n; ++i) {
        if (isPrime(i) && isPrime(reverse(i))) {
            printf("%5d", i);
            ++count;
            if(count % 5 == 0)
                printf("\n");
        }
    }
    return 0;
}
int isPrime(int n) {
    int i, limit, flag = 1;
    if(n <= 1)
        flag = 0;
    else if(n == 2)
        flag = 1;
    else if(n % 2 == 0)
        flag = 0;
    else {
        limit = sqrt(n) + 1;
        for(i = 3; i <= limit; i += 2) {
            if(n % i == 0) {
                flag = 0;
                break;
            }
        }
    }
    return flag;
}
int reverse(int n) {
    int flag = 1;
    int remainder, result = 0;
    if(n < 0) {
        flag = -1;
        n = -n;
    }
    while (n != 0) {
        remainder = n % 10;
        result = result * 10 + remainder;
        n = n / 10;
    }
    return flag * result;
}

第8 题

【描述】
按如下公式:

求出数列的前n项(n≤20)并输出,要求每行输出5项。定义和调用函数:long sequence(int n),计算数列第n项的值。
【输入】
输入一个正整数n。
【输出】
输出数列的前n项。每行输出5项。每项宽度为6。
【输入示例】
20
【输出示例】

     0     1     2     3     6
    11    20    37    68   125
   230   423   778  1431  2632
  4841  8904 16377 30122 55403

【来源】
《程序设计基础——以C为例》第4章上机实验题8。
【参考答案】

#include <stdio.h>
long sequence(int n);
int main(void) {
    int i, n, count = 0;
    scanf("%d", &n);
    for(i = 0; i < n; ++i) {
        printf("%6ld", sequence(i));
        ++count;
        if(count % 5 == 0)
            printf("\n");
    }
    return 0;
}
long sequence(int n) {
    if(n == 0)
        return 0;
    else if(n == 1)
        return 1;
    else if(n == 2)
        return 2;
    else
        return sequence(n - 1) + sequence(n - 2) + sequence( n - 3);
}

第9 题

【描述】
对于任意一个正整数,如果是奇数,则乘3加1,如果是偶数,则除以2,得到的结果再按照上述规则重复处理,最终总能够得到1。例如,假定初始正整数为5,计算过程分别为16、8、4、2、1。要求定义和调用递归函数:guess(n),输出计算过程。
【输入】
输入一个正整数。
【输出】
从输入整数到1的步骤,每一步为一行,每一步中描述计算过程,最后一行输出“End”。如果输入为1,直接输出“End”。
【输入示例】
5
【输出示例】
5*3+1=16
16/2=8
8/2=4
4/2=2
2/2=1
End
【参考答案】

#include <stdio.h>
void guess(long long int n);
int main() {
    long long int n;
    scanf("%lld", &n);
    guess(n);
    return 0;
}
void guess(long long int n) {
       if(n == 1)
        printf("End");
    else if(n % 2) {
        printf("%lld%s%lld\n", n, "*3+1=", n * 3 + 1);
        guess(n * 3 + 1);
    }
    else {
        printf("%lld%s%lld\n", n, "/2=", n / 2);
        guess(n / 2);
    }        
}

第10 题

【描述】
分数可以表示为“分子/分母”的形式。编写一个程序,要求用户输入一个分数,然后将其约分为最简分式。最简分式是指分子和分母不具有可以约分的成分了。如6/12可以被约分为1/2。当分子大于分母时,不需要表达为整数又分数的形式,即11/8还是11/8;而当分子分母相等时,仍然表达为1/1的分数形式。
定义和调用函数:int gcd(int m, int n),求最大公约数。
【输入】
在一行中给出一个分数,分子和分母中间以斜杠“/”分隔,如:12/34表示34分之12。分子和分母都是正整数(不包含0)。
【输出】
在一行中输出这个分数对应的最简分式,格式与输入的相同,即采用“分子/分母”的形式表示分数。如 5/6表示6分之5。
【输入示例】
60/120
【输出示例】
1/2
【参考答案】

#include <stdio.h>
int gcd(int m, int n);
int main(void) {
    int n, d, g;
    scanf("%d/%d", &n, &d);
    g = gcd(n, d);
    n /= g;
    d /= g;
    printf("%d/%d\n", n, d);
    return 0;
}
int gcd(int m, int n) {    /* 求最大公约数 */ 
    int r;
    while(1) {
    r = m % n;
    if(r == 0)
        break;
    m = n;
    n = r;
    }
    return n;
}

练习6

第1 题

【描述】
编写函数重置两个变量的值,该函数的原型为:
void reset(int *a,int *b);
函数内部将两个值重置为两个变量原值的平均数(出现小数则四舍五入)。
【输入】
两个待重置的值
【输出】
重置后的两个值
【输入示例】
7 14
【输出示例】
11 11
【参考答案】

#include <stdio.h>
void reset(int *a, int *b);
int main(void) {
    int a, b;
    scanf("%d%d", &a, &b);
    reset(&a, &b);
    printf("%d %d\n", a, b);
    return 0;
}
void reset(int *a, int *b) {
    int average = ((*a + *b) / 2.0 + 0.5);
    *a = *b = average;
}

第2 题

【描述】
定义和调用swap函数,实现两个整数的交换。函数参数是指针。
在main函数中输入交换前和输出交换后的值。
【输入】
输入的第一行是一个正整数n(1≤n≤100),表示测试数据的总数。
接下来的n行,每行为测试数据,包含交换前的两个整数。
【输出】
输出包括n行,每行为测试结果,包含交换后的两个整数。
【输入示例】
2
12345 67890
213879 7892
【输出示例】
67890 12345
7892 213879
【参考答案】

#include <stdio.h>
void swap(int *i1, int *i2);
int main(void) {
    int i, n;
    int i1, i2;
    scanf("%d", &n);
    for(i = 1; i <= n; ++i) {        
    scanf("%d%d", &i1, &i2);    
    swap(&i1, &i2);
    printf("%d %d\n", i1, i2);
    }
    return 0;
}
void swap(int *i1, int *i2) {
    int temp = *i1;
    *i1 = *i2;
    *i2 = temp;
}

第3 题

【描述】
定义和调用函数:int sum(int (*fp)(int), int start, int end)和int f(int x),f函数的功能是求x的平方;sum函数的功能是求f(start)+…+f(end)的值。
输入两个整数num1和num2,要求num1 <= num2;调用函数sum(f, num1, num2),求出f(num1)+…+f(num2)的值。例如,假设num1为1,num2为5,则f(1)为1、f(2)为4、f(3)为9、f(4)为16、f(5)为25、f(1)+...+f(5)的值为55(1+4+9+16+25)。
【输入】
输入两个整数num1和num2,两个正整数以空格间隔。
【输出】
输出f(num1)+…+f(num2)的值
【输入示例】
1 5
【输出示例】
55
【来源】
《程序设计基础——以C为例》第5章上机实验题1。
【参考答案】

#include <stdio.h>
int f(int);
int sum(int (*fp)(int), int, int);
int main(void) {
    int num1, num2;
    scanf("%d%d", &num1, &num2);
    int result = sum(f, num1, num2);
    printf("%d\n", result);
    return 0;
}
int f(int x) {
    return x * x;
}
int sum(int (*fp)(int), int start, int end) {
    int i, result = 0;
    for(i = start; i <= end; ++i)
        result += fp(i);
    return result;
}

第4 题

【描述】
定义和调用如下函数:
double add(double x, double y);
double sub(double x, double y);
double mul(double x, double y);
double div(double x, double y);
求两个浮点数的和、差、积、商。
要求通过函数指针调用函数。
【输入】
输入两个浮点数num1和num2,两个浮点数以空格间隔。
【输出】
分行输出两个浮点数num1和num2的和、差、积、商。
【输入示例】
10.0 5.0
【输出示例】
15.000000
5.000000
50.000000
2.000000
【来源】
《程序设计基础——以C为例》第5章上机实验题2。
【参考答案】

#include <stdio.h>
double add(double, double);
double sub(double, double);
double mul(double, double);
double div(double, double);
int main(void) {
    double num1, num2, result;
    double (*pf)(double, double);
    scanf("%lf%lf", &num1, &num2);
    pf = add;
    result = pf(num1, num2);
    printf("%lf\n", result);
    pf = sub;
    result = pf(num1, num2);
    printf("%lf\n", result);
    pf = mul;
    result = pf(num1, num2);
    printf("%lf\n", result);
    pf = div;
    result = pf(num1, num2);
    printf("%lf\n", result);
    return 0;
}
double add(double x, double y) {
    return x + y;
}
double sub(double x, double y) {
    return x - y;
}
double mul(double x, double y) {
    return x * y;
}
double div(double x, double y) {
    return x / y;
}

第5 题

【描述】
编写求数学函数区间平均值的通用函数,可以计算出在指定区间内函数的平均值(取整即可)。
待求区间平均值的两个函数的原型为:
int func1(int x);
int func2(int x);
只考虑参数为整数的情况即可。
func1的数学表达式为:
y=a*x^2+b*x+c
x^2表示x的平方,a,b,c由用户输入。
func2的数学表达式为:
y=x^m
x^m表示x的m次方,m由用户输入。
通用函数原型可设为:int avg(int (*f)(int), int x1, intx2);
通用函数的参数为待求区间平均值函数的指针,以及给出的区间下界与上界。
例如:func1=3*x^2+2*x+1,区间下界与上界分别为0和3,则
func1(0)=1
func1(1)=6
func1(2)=17
func1(3)=34
则平均值为:(1+6+17+34)/4=14(直接取整不四舍五入)
【输入】
用户依次输入:
func1的参数:a,b,c
func2的参数:m
给出的区间下界与上界
【输出】
func1的区间内平均值
func2的区间内平均值
【输入示例】
3 2 1
1
0 3
【输出示例】
14
1
【提示】
由于函数原型的限制,a,b,c和m参数可以使用全局变量传递。
【参考答案】

#include <stdio.h>
#include <math.h>
int a, b, c, m;
int func1(int x);
int func2(int x);
int avg(int (*f)(int), int x1, int x2);
int main(void) {
    scanf("%d%d%d", &a, &b, &c);
    scanf("%d", &m);
    int lower, upper;
    scanf("%d%d", &lower, &upper);
    printf("%d\n", avg(func1, lower, upper));
    printf("%d\n", avg(func2, lower, upper));
    return 0;
}
int func1(int x) {
    return a * x * x + b * x + c;
}
int func2(int x) {
    return pow(x, m);
}
int avg(int (*f)(int), int x1, int x2) {
    int n = x2 - x1 + 1;
    int i, sum = 0;
    for(i = x1; i <= x2; ++i)
        sum += f(i);
    return sum / n;
}

系统没有练习7,第7套题就是练习8,以此类推。

练习8

第1 题

【描述】
输入10个整数,存放在一维数组中,找出值最大和最小的元素,输出最大值、最小值及它们所在的元素下标。
【输入】
输入10个整数,整数以空格间隔。
【输出】
第一行输出最大值及其所在的元素下标,最大值和下标以空格间隔。
第二行输出最小值及其所在的元素下标,最小值和下标以空格间隔。
【输入示例】
1 3 5 7 9 6 0 8 2 4
【输出示例】
9 4
0 6
【来源】
《程序设计基础——以C为例》第6章上机实验题1。
【参考答案】

#include <stdio.h>
#define ARRAY_SIZE 10
int main(void) {
    int i, max, min, maxIndex, minIndex;
    int a[ARRAY_SIZE];
    for(i = 0; i < ARRAY_SIZE; ++i)
        scanf("%d", &a[i]);
    max = min = a[0];
    maxIndex = minIndex = 0;
    for(i = 1; i < ARRAY_SIZE; ++i) {
        if(a[i] > max) {
            max = a[i];
            maxIndex = i;
        }
        if(a[i] < min) {
            min = a[i];
            minIndex = i;
        }
    }
    printf("%d %d\n", max, maxIndex);
    printf("%d %d\n", min, minIndex);
    return 0;
}

第2 题

【描述】
输入一个十进制正整数,将它转换为二进制整数并输出。
【输入】
输入一个十进制正整数。
【输出】
输出对应的二进制整数。
【输入示例】
123
【输出示例】
1111011
【提示】
利用循环将十进制整数n转换为二进制数的思路是:反复地将n除以2取余数;将取出的余数用数组存放;由于先取出的是低位数据,后取出的是高位数据,因此需将数组逆序输出。
【来源】
《程序设计基础——以C为例》第6章上机实验题2。
【参考答案】

#include <stdio.h>
#define ARRAY_SIZE 20
int main(void) {
    int a[ARRAY_SIZE];
    int i = 0, n, k;
    scanf("%d", &n);
    while(n > 0) {
        a[i++] = n % 2;
        n = n / 2;
    }
    for(k = i - 1; k >= 0; --k)
        printf("%d", a[k]);
    printf("\n");
    return 0;
}

第3 题

【描述】
给定一组整数,用数组保存整数,实现对数组中的数循环移动。假定共有n个整数,则要使前面各数顺序向后移m个位置,并使最后m个数变为最前面的m个数。
要求只用一个数组的方式实现,一定要保证在输出结果时,输出的顺序和数组中数的顺序是一致的。
【输入】
第一行包含一个正整数n(n≤100)和一个正整数m(m≤n),n和m以空格间隔。
第二行包含n个正整数,整数以空格间隔。
【输出】
依次输出经过循环移动后数组中元素值,元素值以空格间隔。最后一个元素后面没有空格。
【输入示例】
11 4
15 3 76 67 84 87 13 67 45 34 45
【输出示例】
67 45 34 45 15 3 76 67 84 87 13
【参考答案】

#include <stdio.h>
#define ARRAY_SIZE 100
int main(void) {
    int i, j, n, m, temp;
    int array[ARRAY_SIZE];
    scanf("%d%d", &n, &m);
    for(i = 0; i < n; ++i)
        scanf("%d", &array[i]);
    for(i = 1; i <= m; ++i) {
        temp = array[n - 1];
        for(j = 1; j < n; ++j) {
            array[n - j] = array[n - j - 1];
        }
        array[0] = temp;
    }
    for(i = 0; i < n - 1; ++i)
        printf("%d ", array[i]);
    printf("%d", array[n - 1]);
    printf("\n");
    return 0;
}

第4 题

【描述】
输入n个正整数(无序的),找出第k大的数。注意,第k大的数意味着从大到小排在第k位置的数。
【输入】
n(n≤100)
k
a1 a2 a3 a4 ... an
输出
b
【输入示例】
5
2
32 3 12 5 89
【输出示例】
32
【参考答案】

#include <stdio.h>
#include <stdlib.h>
#define ARRAY_SIZE 100
int comp(const void *p, const void *q) {
    return *((int *)q) - *((int *)p);
}
int main(void) {
    int i, n, k;
    int array[ARRAY_SIZE];
    scanf("%d", &n);
    scanf("%d", &k);
    for(i = 0; i < n; ++i) {
    scanf("%d", &array[i]);
    }
    qsort(array, n, sizeof(int), comp);
    printf("%d\n", array[k - 1]);
    return 0;
}

第5 题

【描述】
输入一个正整数n(2≤n≤10)和n×n矩阵a中的元素,如果a是上三角矩阵,输出“Yes”,否则输出“No”。
【输入】
第一行为正整数n,表示矩阵大小。
接着n行,每一行n个整数,整数以空格间隔。
【输出】
输出“Yes”或“No”。
【输入示例】
3
3 4 5
1 2 3
1 3 4
【输出示例】
No
【提示】
用二维数组表示n×n矩阵时(i表示行下标,j表示列下标),则:
主对角线i==j,副对角线i + j == n – 1
上三角矩阵i<=j
下三角矩阵i>=j
【来源】
《程序设计基础——以C为例》第6章上机实验题5。
【参考答案】

#include <stdio.h>
#define ARRAY_SIZE 10
int main(void) {
    int a[ARRAY_SIZE][ARRAY_SIZE];
    int i, j, n, flag;
    scanf("%d", &n);
    for(i = 0; i < n; ++i)
        for(j = 0; j < n; ++j)
            scanf("%d", &a[i][j]);
    flag = 1;
    for(i = 0; i < n; ++i) {
        for(j = 0; j < i; ++j) {
            if(a[i][j] != 0) {
                flag = 0;
                break;
            }
        }
    }
    printf(flag ? "Yes" : "No");
    return 0;
}

第6 题

【描述】
输入一个4×4的整数矩阵,求该矩阵的外围元素之和,主对角线元素之和以及副对角线元素之和。
【输入】
输入一个4×4的整数矩阵。
分4行,每行4个整数,整数之间以空格间隔。
【输出】
分行输出矩阵的外围元素之和,主对角线元素之和以及副对角线元素之和。
【输入示例】
1 2 4 5
6 7 8 9
0 1 2 3
4 5 6 7
【输出示例】
52
17
18
【提示】
求三类元素的和,可以定义三个不同的和变量,在遍历数组元素的循环中通过三次条件判断分别进行三类元素的求和。设行下标为i,列下标为j,考察三类元素的下标特征,外围元素要么行下标i == 0或者i == n - 1(这里n为4),要么列下标j ==0或者j == n - 1;主对角线上的元素行下标和列下标相等(i == j);副对角线上的元素行下标和列下标之和等于n - 1(i + j == n - 1)。
【来源】
《程序设计基础——以C为例》第6章上机实验题6。
【参考答案】

#include <stdio.h>
#define ARRAY_SIZE 4
int main(void) {
    int i, j;
    int sum1 = 0, sum2 = 0, sum3 = 0;
    int a[ARRAY_SIZE][ARRAY_SIZE];
    for(i = 0; i < ARRAY_SIZE; ++i) {
        for(j = 0; j < ARRAY_SIZE; ++j) {
        scanf("%d", &a[i][j]);
        }
    }
    for(i = 0; i < ARRAY_SIZE; ++i) {
        for(j = 0; j < ARRAY_SIZE; ++j) {
            if(i == 0 || i == ARRAY_SIZE - 1 || j == 0 || j == ARRAY_SIZE - 1)
                sum1 += a[i][j];
            if(i == j)
                sum2 += a[i][j];
            if(i + j == ARRAY_SIZE - 1)
                sum3 += a[i][j];
        }
    }
    printf("%d\n", sum1);
    printf("%d\n", sum2);
    printf("%d\n", sum3);
    return 0;
}

第7 题

【描述】
以左下三角的形式输出杨辉三角形。
【输入】
输入一个正整数n(n≤10)。
【输出】
输出n行杨辉三角形。每个数宽度为4。
【输入示例】
5
【输出示例】

   1
   1   1
   1   2   1
   1   3   3   1
   1   4   6   4   1

【提示】
以左下三角的形式输出杨辉三角形,用主对角线作为0元素和非0元素的分界线。假设i和j分别表示二维数组的行、列下标。
①三角形两条腰上的元素均为1。两条腰一个为第0列,一个为主对角线。
②除两腰外,三角形覆盖的其余元素等于其两肩元素之和(上一行前一列元素和上一行同一列元素之和)。
【来源】
《程序设计基础——以C为例》第6章上机实验题8。
【参考答案】

#include <stdio.h>
#define ARRAY_SIZE 10
int main(void) {
    int a[ARRAY_SIZE][ARRAY_SIZE];
    int i, j, n;
    scanf("%d", &n);
    for(i = 0; i < n; ++i) {
        for(j = 0; j < n; ++j) {
            if(j == 0 || i == j)
                a[i][j] = 1;
            if(j > 0 && i > j)
                a[i][j] = a[i - 1][j - 1] + a[i - 1][j];
        }
    }
    for(i = 0; i < n; ++i) {
        for(j = 0; j < n; ++j) {
            if(i >= j) {
                printf("%4d", a[i][j]);
            }
        }
        printf("\n");
    }
    return 0;
}

第8 题

【描述】
编写一个函数:int swap(int array 5, int n, int m ),输入参数是5×5的二维数组,和n、m两个行下标。功能:判断n、m是否在数组范围内,如果不在,则返回0;如果在范围内,则将n行元素与m行元素交换,并返回1。
在main函数中, 创建一个5×5的矩阵,输入矩阵数据,并输入n、m的值。调用前面的函数。如果返回值为0,输出error。如果返回值为1,输出交换n、m行后的新矩阵。
【输入】
5×5矩阵的数据,以及n和m的值。
【输出】
如果不可交换,则输出error;如果可交换,则输出新矩阵。
【输入示例】
1 2 2 1 2
5 6 7 8 3
9 3 0 5 3
7 2 1 4 6
3 0 8 2 4
0 4
【输出示例】

   3   0   8   2   4
   5   6   7   8   3
   9   3   0   5   3
   7   2   1   4   6
   1   2   2   1   2

【提示】
输出error格式如下:
printf("errorn");
输出矩阵元素格式如下:
printf("%4d", num);
输出矩阵一行后要换行:
printf("n");
【参考答案】

#include <stdio.h>
int swap(int array[5][5], int n, int m);
int main(void) {
    int i, j;
    int n, m, flag;
    int array[5][5];
    for(i = 0; i < 5; ++i) {
    for(j = 0; j < 5; ++j) {
            scanf("%d", &array[i][j]);
        }
    }
    scanf("%d%d", &n, &m);
    flag = swap(array, n, m);
    if(flag) {
        for(i = 0; i < 5; ++i) {
            for(j = 0; j < 5; ++j) {
                 printf("%4d", array[i][j]);
            }
            printf("\n");
        }
    }
    else
        printf("error\n");
    return 0;
}
int swap(int array[5][5], int n, int m) {
    int i, temp;
    if((n >= 0 && n < 5) && ( m >= 0 && m < 5)) {
        for(i = 0; i < 5; ++i) {
            temp = array[n][i];
            array[n][i] = array[m][i];
            array[m][i] = temp;
        }
        return 1;
    }
    else
        return 0;
}

第9 题

【描述】
拍摄的一张CT照片用一个二维数组来存储,假设数组中的每个点代表一个细胞。每个细胞的颜色用0到255之间(包括0和255)的一个整数表示。定义一个细胞是异常细胞,如果这个细胞的颜色值比它上下左右4个细胞的颜色值都小50以上(包括50)。数组边缘上的细胞不检测。现在的任务是,给定一个存储CT照片的二维数组,写程序统计照片中异常细胞的数目。
【输入】
第一行包含一个整数n(2 < n <= 100)。
下面有n行,每行有n个0~255之间的整数,整数以空格间隔。
【输出】
输出一个整数,即异常细胞的数目。
【输入示例】
4
70 70 70 70
70 10 70 70
70 70 20 70
70 70 70 70
【输出示例】
2
【参考答案】

#include <stdio.h>
#include <stdlib.h>
int main() {
    int array[100][100];
    int i, j, n;
    int count, left, right, top, bottom;
    scanf("%d", &n);
    for(i = 0; i < n; ++i) {
        for(j = 0; j < n; ++j) {
            scanf("%d", &array[i][j]);
        }
    }
    count = 0;
    for(i = 1; i < n - 1; ++i) {
        for(j = 1; j < n - 1; ++j) {
            int left = abs(array[i][j] - array[i][j - 1]) >= 50;
            int right = abs(array[i][j] - array[i][j + 1]) >= 50;
            int top = abs(array[i][j] - array[i - 1][j]) >= 50;
            int bottom = abs(array[i][j] - array[i + 1][j]) >= 50;
            if(left && right && top && bottom)
                ++count;
        }
    }
    printf("%d\n", count);
    return 0;
}

第10 题

【描述】
中位数定义:一组数据按从小到大的顺序依次排列,处在中间位置的一个数或最中间两个数据的平均值(如果这组数的个数为奇数,则中位数为位于中间位置的那个数;如果这组数的个数为偶数,则中位数是位于中间位置的两个数的平均值)。
给出一组无序整数,求出中位数,如果求最中间两个数的平均数,向下取整即可(不需要使用浮点数)。
【输入】
包含多组测试数据,每一组测试数据的第一行为n,代表该组测试数据包含的数据个数,1 <= n <=10000。
接着n行为n个数据。n为0时结束输入。
【输出】
输出中位数,每一组测试数据输出一行。
【输入示例】
4
10
30
20
40
3
40
30
50
4
1
2
3
4
0
【输出示例】
25
40
2
【参考答案】

#include <stdio.h>
#include <stdlib.h>
#define ARRAY_SIZE 1000
int comp(const void *p, const void *q) {
    return *(int *)p - *(int *)q;
}
int main(void) {
    int array[ARRAY_SIZE];
    int i, n;
    while(1) {
        scanf("%d", &n); 
        if(!n)
            break;
        for(i = 0; i < n; ++i)
            scanf("%d", &array[i]);
        qsort(array, n, sizeof(int), comp);
        if(n % 2 != 0)
            printf("%d\n", array[n / 2]);
        else
            printf("%d\n", (array[n / 2 - 1] + array[n / 2]) / 2);
    }
    return 0;
}

练习9

第1 题

【描述】
判断输入的一个字符串是否为回文串,若是输出“Yes”,否则输出“No”。回文串是指正读和反读都一样的字符串,如level。
【输入】
输入一个字符串。
【输出】
输出“Yes”或“No”。
【输入示例】
abcddcba
【输出示例】
Yes
【来源】
《程序设计基础——以C为例》第6章上机实验题9。
【参考答案】

#include <stdio.h>
#include <string.h>
#define STRING_LENGTH 80
int main(void) {
    char str[STRING_LENGTH + 1];
    int flag = 1;
    int loc1, loc2;
    gets(str);
    loc1 = 0;
    loc2 = strlen(str) - 1;
    while(loc1 < loc2) {
        if(str[loc1] != str[loc2]) {
            flag = 0;
            break;
        }
        loc1++;
        loc2--;
    }
    printf(flag ? "Yes" : "No");
    return 0;
}

第2 题

【描述】
输入一个字符串,统计并输出该字符串中大写辅音字母的个数(大写辅音字母:除A、E、I、O、U以外的大写字母)。
【输入】
输入一个字符串。
【输出】
输出大写辅音字母的个数。
【输入示例】
HELLO
【输出示例】
3
【来源】
《程序设计基础——以C为例》第6章上机实验题10。
【参考答案】


#include <stdio.h>
#include <ctype.h>
#define STRING_LENGTH 80
int main(void) {
    int count, i, j, flag;
    char upperVowel[] = {'A', 'E', 'I', 'O', 'U', '\0'};
    char str[STRING_LENGTH + 1];
    gets(str);
    count = 0;
    for(i = 0; str[i] != '\0'; ++i) {
        if(isupper(str[i])) {
            flag = 1;
            for(j = 0; upperVowel[j] != '\0'; ++j) {
                if(str[i] == upperVowel[j]) {
                    flag = 0;
                    break;
                }
            }
            if(flag)
                ++count;
        }
    }
    printf("%d\n", count);
    return 0;
}

第3 题

【描述】
输入一个字符串,统计并输出该字符串中26个英文字母(不区分大小写)出现的次数。
【输入】
输入一个字符串。
【输出】
分行输出26个英文字母(不区分大小写)出现的次数。
【输入示例】
I am a student.
【输出示例】
a:2
d:1
e:1
i:1
m:1
n:1
s:1
t:2
u:1
【来源】
《程序设计基础——以C为例》第6章上机实验题11。
【参考答案】

#include <stdio.h>
#include <ctype.h>
#define STRING_LENGTH 80
int main(void) {
    int i;
    char count[26] = {0};
    char str[STRING_LENGTH + 1];
    gets(str);
    for(i = 0; str[i] != '\0'; ++i) {
        if(isalpha(str[i])) {
            if(isupper(str[i]))
                str[i] = tolower(str[i]);
            ++count[str[i] - 'a'];
        }
    }
    for(i = 0; i < 26; ++i)
        if(count[i] != 0)
            printf("%c:%d\n", 'a' + i, count[i]);
    return 0;
}

第4 题

【描述】
输入5个字符串,输出其中最大的字符串。
【输入】
输入5个字符串。
【输出】
输出5个字符串中最大的字符串。
【输入示例】
red
blue
yellow
green
purple
【输出示例】
yellow
【来源】
《程序设计基础——以C为例》第6章上机实验题12。
【参考答案】

#include <stdio.h>
#include <string.h>
#define STRING_LENGTH 80
int main(void) {
    int i;
    char max[STRING_LENGTH + 1];
    char str[5][STRING_LENGTH + 1];
    for(i = 0; i < 5; ++i)
        gets(str[i]);
    strcpy(max, str[0]);
    for(i = 1; i < 5; ++i)
        if(strcmp(max, str[i]) < 0)
            strcpy(max, str[i]);
    printf("%s\n", max);
    return 0;
}

第5 题

【描述】
定义和调用函数:int isAnagram(char *str1, char *str2),检查两个单词是否是字母易位词,若是易位词,返回1,否则返回0。两个单词如果包含相同的字母,次序不同,则称为字母易位词(anagram)。例如,“silent”和“listen”是字母易位词。
【输入】
输入有两行,分别对应两个单词。
【输出】
若两个单词是字母易位词,输出true,否则输出false。
【输入示例】
silent
listen
【输出示例】
true
【来源】
《程序设计基础——以C为例》第6章上机实验题12。
【参考答案】

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define STRING_LENGTH 80
int isAnagram(char *str1, char *str2);
int comp(const void *p, const void *q) {
    return strcmp((char *)p, (char *)q);
}
int main(void) {
    char str1[STRING_LENGTH + 1], str2[STRING_LENGTH + 1];
    gets(str1);
    gets(str2);
    printf(isAnagram(str1, str2) ? "true" : "false");
    return 0;
}
int isAnagram(char *str1, char *str2) {
    char newStr1[STRING_LENGTH + 1], newStr2[STRING_LENGTH + 1];
    strcpy(newStr1, str1);
    strcpy(newStr2, str2);
    qsort(newStr1, strlen(newStr1), sizeof(char), comp);
    qsort(newStr2, strlen(newStr2), sizeof(char), comp);
    if(strlen(newStr1) != strlen(newStr2))
        return 0;
    if(strcmp(newStr1, newStr2) != 0)
        return 0;
    return 1;
}

第6 题

【描述】
脱氧核糖核酸(DNA)由两条互补的碱基链以双螺旋的方式结合而成。而构成DNA的碱基共有4种,分别为腺瞟呤(A)、鸟嘌呤(G)、胸腺嘧啶(T)和胞嘧啶(C)。在两条互补碱基链的对应位置上,腺瞟呤总是和胸腺嘧啶配对,鸟嘌呤总是和胞嘧啶配对。你的任务就是根据一条单链上的碱基序列,给出对应的互补链上的碱基序列。
【输入】
第一行是一个正整数n,表明共有n条要求解的碱基链。
以下共有n行,每行用一个字符串表示一条碱基链。这个字符串只含有大写字母A、T、G、C,分别表示腺瞟呤、胸腺嘧啶、鸟嘌呤和胞嘧啶。每条碱基链的长度都不超过255。
【输出】
共有n行,每行为一个只含有大写字母A、T、G、C的字符串。分别为与输入的各碱基链互补的碱基链。
【输入示例】
5
ATATGGATGGTGTTTGGCTCTG
TCTCCGGTTGATT
ATATCTTGCGCTCTTGATTCGCATATTCT
GCGTTTCGTTGCAA
TTAACGCACAACCTAGACTT
【输出示例】
TATACCTACCACAAACCGAGAC
AGAGGCCAACTAA
TATAGAACGCGAGAACTAAGCGTATAAGA
CGCAAAGCAACGTT
AATTGCGTGTTGGATCTGAA
【参考答案】

#include <stdio.h>
#include <string.h>
#define STRING_SIZE 255
int main(void) {
    char str[STRING_SIZE + 1];
    int i, n, len;
    scanf("%d", &n);
    getchar();    /* 跳过回车符 */
    while(n--) {
    gets(str);
    len = strlen(str);
    for(i = 0; i < len; ++i) {
        switch(str[i]) {
        case 'A' :
            printf("%c", 'T');
            break;
        case 'C' :
            printf("%c", 'G');
            break;
        case 'G' :
            printf("%c", 'C');
            break;
        case 'T' :
            printf("%c", 'A');
            break;
        }
    }
    printf("\n");
    }
    return 0;
}

第7 题

【描述】
比较两个字符串的大小,比较方法为对两个字符串从前往后逐个字符相比较(按ASCII码值大小比较),直到出现不同的字符或遇到字符串结束为止。如果全部字符都相同,则认为相同;如果出现不相同的字符,则以第一个不相同的字符的比较结果为准。但在有些时候,比较字符串的大小时,希望忽略字母的大小,例如“Hello”和“hello”在忽略字母大小写时是相等的。请写一个程序,实现对两个字符串进行忽略字母大小写的大小比较。
【输入】
输入为两行,每行一个字符串,共两个字符串(每个字符串长度都小于80)。
【输出】
如果第一个字符串比第二个字符串小,输出一个字符"<"
如果第一个字符串比第二个字符串大,输出一个字符">"
如果两个字符串相等,输出一个字符"="
【输入示例】
Hello
hello
【输出示例】
=
【参考答案】

#include <stdio.h>
#include <string.h>
#include <ctype.h>
#define STRING_SIZE 80
int main(void) {
    char str1[STRING_SIZE + 1];
    char str2[STRING_SIZE + 1];
    int i, comp, len1, len2;
    gets(str1);
    gets(str2);
    len1 = strlen(str1);
    len2 = strlen(str2);
    for(i = 0; i < len1; ++i) {
    if(isalpha(str1[i]) && isupper(str1[i]))
        str1[i] = tolower(str1[i]);
    }
    for(i = 0; i < len2; ++i) {
    if(isalpha(str2[i]) && isupper(str2[i]))
        str2[i] = tolower(str2[i]);
    }
    comp = strcmp(str1, str2);
    if(comp > 0)
        printf(">\n");
    else if(comp == 0)
        printf("=\n");
    else
        printf("<\n");
    return 0;
}

第8 题

【描述】
有两个字符串str和substr,str的字符个数不超过10,substr的字符个数为3。将substr插入到str中ASCII码最大的那个字符后面,若有多个最大则只考虑第一个。
【输入】
输入包括若干行,每一行为一组测试数据,格式为
str substr
【输出】
对于每一组测试数据,输出插入之后的字符串。
【输入示例】
abcab eee
12343 555
【输出示例】
abceeeab
12345553
【参考答案】

#include <stdio.h>
#include <string.h>
#define STRING_SIZE 11
int main(void) {
    char str[STRING_SIZE], substr[4];
    int i, len;
    char maxChar;
    int maxIndex;
    while(scanf("%s", str) == 1) {
        scanf("%s", substr);
        len = 0;
        maxChar = 0;
        maxIndex = 0;
        len = strlen(str);
        for(i = 0; i < len; ++i) {
            if(str[i] > maxChar) {
                maxChar = str[i];
                maxIndex = i;
            }
        }
        for(i = 0; i <= maxIndex; ++i)
            printf("%c", str[i]);
        printf("%s", substr);
        for(i = maxIndex + 1; i < STRING_SIZE; ++i) {
            if(str[i] == '\0')
                break;
               printf("%c", str[i]);
        }
        printf("\n");
    }
    return 0;
}

第9 题

【描述】
一个以'.'结尾的简单英文句子,单词之间用空格分隔,没有缩写形式和其它特殊形式。
【输入】
一个以'.'结尾的简单英文句子(长度不超过500),单词之间用空格分隔,没有缩写形式和其它特殊形式。
【输出】
该句子中最长的单词。如果多于一个,则输出第一个。
【输入示例】
I am a student of Hangzhou Normal University.
【输出示例】
University
【参考答案】

#include <stdio.h>
#include <string.h>
#define STRING_SIZE 80
int main(void) {
    int maxLength = 0;
    int tempLength;
    char word[STRING_SIZE + 1];
    char temp[STRING_SIZE + 1];
    while(1) {
    scanf("%s", temp);
    tempLength = strlen(temp);
    if(temp[tempLength - 1] == '.')
        --tempLength;        
    if(tempLength > maxLength) {
        maxLength = tempLength;
        strncpy(word, temp, tempLength);
        word[maxLength] = '\0';
        }
        if(temp[tempLength] == '.')
        break;
    }
    printf("%s\n", word);
    return 0;
}

第10 题

【描述】
给定t个字符串,这个字符串只可能由26个小写字母组成。
请你找到第一个仅出现一次的字符,如果没有符合要求的字符,就输出“no”。
【输入】
第一行是正整数n,接下来是n个字符串,每个字符串长度小于100000。
【输出】
输出由n行组成。
对于每个字符串,输出第一个仅出现一次的字符,没有输出“no”。
【输入示例】
2
aabb
abcabd
【输出示例】
no
c
【参考答案】

#include <stdio.h>
#include <string.h>
#define STRING_SIZE 100000
int main(void) {
    char str[STRING_SIZE + 1];
    int i, j, k, n, len, find, flag;
    scanf("%d", &n);
    getchar();    /* 跳过回车符 */
    for(i = 0; i < n; ++i) {
    gets(str);
    len = strlen(str);
    find = 1;    /* 是否存在符合要求的字符,1表示存在 */ 
    for(j = 0; j < len; ++j) {
        flag = 0;    /* 元素是否重复,0表示不重复 */ 
        for(k = 0; k < len; ++k) {
        if((str[j] == str[k]) && (j != k)) {        
            flag = 1;        /* 重复 */
            find = 0;        /* 不存在符合要求的字符 */ 
            break;
        }
        }
        if(!flag) {
        printf("%c\n", str[j]);
        find = 1;
        break;
        }
    }
    if(!find)
        printf("no\n");
    }
    return 0;
}

练习10

第1 题

【描述】
编写函数重置两个变量的值,该函数的原型为:
void reset(int *a,int *b);
函数内部将两个值重置为两个变量原值的平均数(出现小数则四舍五入)。
【输入】
两个待重置的值
【输出】
重置后的两个值
【输入示例】
7 14
【输出示例】
11 11
【参考答案】

#include <stdio.h>
void reset(int *a, int *b);
int main(void) {
    int a, b;
    scanf("%d%d", &a, &b);
    reset(&a, &b);
    printf("%d %d\n", a, b);
    return 0;
}
void reset(int *a, int *b) {
    int average = ((*a + *b) / 2.0 + 0.5);
    *a = *b = average;
}

第2 题

【描述】
定义和调用swap函数,实现两个整数的交换。函数参数是指针。
在main函数中输入交换前和输出交换后的值。
【输入】
输入的第一行是一个正整数n(1≤n≤100),表示测试数据的总数。
接下来的n行,每行为测试数据,包含交换前的两个整数。
【输出】
输出包括n行,每行为测试结果,包含交换后的两个整数。
【输入示例】
2
12345 67890
213879 7892
【输出示例】
67890 12345
7892 213879
【参考答案】

#include <stdio.h>
void swap(int *i1, int *i2);
int main(void) {
    int i, n;
    int i1, i2;
    scanf("%d", &n);
    for(i = 1; i <= n; ++i) {        
    scanf("%d%d", &i1, &i2);    
    swap(&i1, &i2);
    printf("%d %d\n", i1, i2);
    }
    return 0;
}
void swap(int *i1, int *i2) {
    int temp = *i1;
    *i1 = *i2;
    *i2 = temp;
}

第3 题

【描述】
定义和调用函数:int sum(int (*fp)(int), int start, int end)和int f(int x),f函数的功能是求x的平方;sum函数的功能是求f(start)+…+f(end)的值。
输入两个整数num1和num2,要求num1 <= num2;调用函数sum(f, num1, num2),求出f(num1)+…+f(num2)的值。例如,假设num1为1,num2为5,则f(1)为1、f(2)为4、f(3)为9、f(4)为16、f(5)为25、f(1)+...+f(5)的值为55(1+4+9+16+25)。
【输入】
输入两个整数num1和num2,两个正整数以空格间隔。
【输出】
输出f(num1)+…+f(num2)的值
【输入示例】
1 5
【输出示例】
55
【来源】
《程序设计基础——以C为例》第5章上机实验题1。
【参考答案】

#include <stdio.h>
int f(int);
int sum(int (*fp)(int), int, int);
int main(void) {
    int num1, num2;
    scanf("%d%d", &num1, &num2);
    int result = sum(f, num1, num2);
    printf("%d\n", result);
    return 0;
}
int f(int x) {
    return x * x;
}
int sum(int (*fp)(int), int start, int end) {
    int i, result = 0;
    for(i = start; i <= end; ++i)
        result += fp(i);
    return result;
}

第4 题

【描述】
定义和调用如下函数:
double add(double x, double y);
double sub(double x, double y);
double mul(double x, double y);
double div(double x, double y);
求两个浮点数的和、差、积、商。
要求通过函数指针调用函数。
【输入】
输入两个浮点数num1和num2,两个浮点数以空格间隔。
【输出】
分行输出两个浮点数num1和num2的和、差、积、商。
【输入示例】
10.0 5.0
【输出示例】
15.000000
5.000000
50.000000
2.000000
【来源】
《程序设计基础——以C为例》第5章上机实验题2。
【参考答案】

#include <stdio.h>
double add(double, double);
double sub(double, double);
double mul(double, double);
double div(double, double);
int main(void) {
    double num1, num2, result;
    double (*pf)(double, double);
    scanf("%lf%lf", &num1, &num2);
    pf = add;
    result = pf(num1, num2);
    printf("%lf\n", result);
    pf = sub;
    result = pf(num1, num2);
    printf("%lf\n", result);
    pf = mul;
    result = pf(num1, num2);
    printf("%lf\n", result);
    pf = div;
    result = pf(num1, num2);
    printf("%lf\n", result);
    return 0;
}
double add(double x, double y) {
    return x + y;
}
double sub(double x, double y) {
    return x - y;
}
double mul(double x, double y) {
    return x * y;
}
double div(double x, double y) {
    return x / y;
}

第5 题

【描述】
编写求数学函数区间平均值的通用函数,可以计算出在指定区间内函数的平均值(取整即可)。
待求区间平均值的两个函数的原型为:
int func1(int x);
int func2(int x);
只考虑参数为整数的情况即可。
func1的数学表达式为:
y=a*x^2+b*x+c
x^2表示x的平方,a,b,c由用户输入。
func2的数学表达式为:
y=x^m
x^m表示x的m次方,m由用户输入。
通用函数原型可设为:int avg(int (*f)(int), int x1, intx2);
通用函数的参数为待求区间平均值函数的指针,以及给出的区间下界与上界。
例如:func1=3*x^2+2*x+1,区间下界与上界分别为0和3,则
func1(0)=1
func1(1)=6
func1(2)=17
func1(3)=34
则平均值为:(1+6+17+34)/4=14(直接取整不四舍五入)
【输入】
用户依次输入:
func1的参数:a,b,c
func2的参数:m
给出的区间下界与上界
【输出】
func1的区间内平均值
func2的区间内平均值
【输入示例】
3 2 1
1
0 3
【输出示例】
14
1
【提示】
由于函数原型的限制,a,b,c和m参数可以使用全局变量传递。
【参考答案】

#include <stdio.h>
#include <math.h>
int a, b, c, m;
int func1(int x);
int func2(int x);
int avg(int (*f)(int), int x1, int x2);
int main(void) {
    scanf("%d%d%d", &a, &b, &c);
    scanf("%d", &m);
    int lower, upper;
    scanf("%d%d", &lower, &upper);
    printf("%d\n", avg(func1, lower, upper));
    printf("%d\n", avg(func2, lower, upper));
    return 0;
}
int func1(int x) {
    return a * x * x + b * x + c;
}
int func2(int x) {
    return pow(x, m);
}
int avg(int (*f)(int), int x1, int x2) {
    int n = x2 - x1 + 1;
    int i, sum = 0;
    for(i = x1; i <= x2; ++i)
        sum += f(i);
    return sum / n;
}

练习11

第1 题

【描述】
本题要求编写程序,比较两个有理数的大小。
【输入】
输入在一行中按照“a1/b1 a2/b2”的格式给出两个分数形式的有理数,其中分子和分母全是整型范围内的正整数。
【输出】
在一行中按照“a1/b1 关系符 a2/b2”的格式输出两个有理数的关系。其中“>”表示“大于”,“<”表示“小于”,“=”表示“等于”。
【输入示例1】
1/2 3/4
【输出示例1】
1/2 < 3/4
【输入示例2】
6/8 3/4
【输出示例2】
6/8 = 3/4
【参考答案】

#include <stdio.h>
struct Rational {
    int n;    /* 分子 */ 
    int d;    /* 分母 */ 
};
int main(void) {
    struct Rational r1, r2;
    int flag;
    char ch;
    scanf("%d/%d %d/%d", &r1.n, &r1.d, &r2.n, &r2.d);
    flag = r1.n * r2.d - r1.d * r2.n;
    if(flag < 0)
    ch = '<';
    else if(flag > 0)
    ch = '>';
    else
    ch = '=';
    printf("%d/%d %c %d/%d\n", r1.n, r1.d, ch, r2.n, r2.d);
    return 0; 
}

第2 题

【描述】
本题要求编写程序,计算两个有理数的和。
【输入】
输入在一行中按照“a1/b1 a2/b2”的格式给出两个分数形式的有理数,其中分子和分母全是整型范围内的正整数。
【输出】
在一行中按照“a/b”的格式输出两个有理数的和。注意必须是该有理数的最简分数形式,若分母为1,则只输出分子。
【输入示例1】
1/3 1/6
【输出示例1】
1/2
【输入示例2】
4/3 2/3
【输出示例2】
2
【参考答案】

#include <stdio.h>
struct Rational {
    int n;    /* 分子 */ 
    int d;    /* 分母 */ 
};
int gcd(int m, int n) {    /* 求最大公约数 */ 
    int r;
    while(1) {
    r = m % n;
    if(r == 0)
        break;
    m = n;
    n = r;
    }
    return n;
}
int main(void) {
    struct Rational r1, r2, r3;
    int g;
    scanf("%d/%d %d/%d", &r1.n, &r1.d, &r2.n, &r2.d);
    r3.n = r1.n * r2.d + r1.d * r2.n;
    r3.d = r1.d * r2.d;
    g = gcd(r3.n, r3.d);
    r3.n /= g;
    r3.d /= g;
    if(r3.d == 1)
    printf("%d\n", r3.n);
    else
    printf("%d/%d\n", r3.n, r3.d);
    return 0; 
}

第3 题

【描述】
本题要求编写程序,计算N个有理数的平均值。
【输入】
输入第1行给出正整数N(≤100);第2行中按照“a1/b1 a2/b2 ……”的格式给出N个分数形式的有理数,其中分子和分母全是整型范围内的整数;如果是负数,则负号一定出现在最前面。
【输出】
在一行中按照“a/b”的格式输出N个有理数的平均值。注意必须是该有理数的最简分数形式,若分母为1,则只输出分子。
【输入示例1】
4
1/2 1/6 3/6 -5/10
【输出示例1】
1/6
【输入示例2】
2
4/3 2/3
【输出示例2】
1
【参考答案】

#include <stdio.h>
#define N 100
struct Rational {
    int n;    /* 分子 */ 
    int d;    /* 分母 */ 
};
int gcd(int m, int n) {    /* 求最大公约数 */ 
    int r;
    if(m == 0 && n == 0)
        return 0;
    if(m == 0)
        return n;
    if(n == 0)
        return m;
    while(1) {
        r = m % n;
        if(r == 0)
            break;
        m = n;
        n = r;
    }
    return n;
}
int main(void) {
    struct Rational ra[N], r;
    int i, n, g;
    scanf("%d", &n);
    for(i = 0; i < n; ++i)
        scanf("%d/%d", &ra[i].n, &ra[i].d);
    r.n = 0;
    r.d = 1;
    for(i = 0; i < n; ++i) {
        r.n = r.n * ra[i].d + r.d * ra[i].n;
        r.d = r.d * ra[i].d;
    }
    r.d *= n;    /*平均值 */ 
    g = gcd(r.n, r.d);
    if(g != 0) {
        r.n /= g;
        r.d /= g;
    }
    if(r.n == 0)
        printf("%d\n", r.n);    
    else if(r.d == 1)
        printf("%d\n", r.n);
    else
        printf("%d/%d\n", r.n, r.d);
    return 0; 
}

第4 题

【描述】
通讯录中的一条记录包含下述基本信息:朋友的姓名、出生日期、性别、固定电话号码、移动电话号码。本题要求编写程序,录入N条记录,并且根据要求显示任意某条记录。
【输入】
输入在第1行给出正整数N(≤10);随后N行,每行按照格式“姓名 生日 性别 固话 手机”给出一条记录。其中“姓名”是不超过10个字符、不包含空格的非空字符串;生日按“yyyy/mm/dd”的格式给出年月日;性别用“M”表示“男”、“F”表示“女”;“固话”和“手机”均为不超过15位的连续数字,前面有可能出现“+”。
在通讯录记录输入完成后,最后一行给出正整数K,并且随后给出K个整数,表示要查询的记录编号(从0到N-1顺序编号)。数字间以空格分隔。
【输出】
对每一条要查询的记录编号,在一行中按照“姓名 固话 手机 性别 生日”的格式输出该记录。若要查询的记录不存在,则输出“Not Found”。
【输入示例】
3
Chris 1984/03/10 F +86181779452 13707010007
LaoLao 1967/11/30 F 057187951100 +8618618623333
QiaoLin 1980/01/01 M 84172333 10086
2 1 7
【输出示例】
LaoLao 057187951100 +8618618623333 F 1967/11/30
Not Found
【参考答案】

#include <stdio.h>
#define N 10
struct Person {
    char name[11];        /* 名字 */ 
    char birthday[11];    /* 生日 */ 
    char sex;        /* 性别 */ 
    char fixed[17];        /* 固话 */ 
    char mobile[17];    /* 手机 */ 
};
int main(void) {
    struct Person p[N];
    int num[N];
    int i, n, k;
    scanf("%d", &n);
    for(i = 0; i < n; ++i)
        scanf("%s %s %c %s %s", p[i].name, p[i].birthday, 
              &p[i].sex, p[i].fixed, p[i].mobile);
    scanf("%d", &k);
    for(i = 0; i < k; ++i)
        scanf("%d", &num[i]);
    for(i = 0; i < k; ++i) {
        if(num[i] >= 0 && num[i] < n)
            printf("%s %s %s %c %s\n", p[num[i]].name, 
                   p[num[i]].fixed, p[num[i]].mobile, p[num[i]].sex, p[num[i]].birthday);
        else
            printf("Not Found\n");
    }
    return 0;
}

第5 题

【描述】
建立一个通讯录结构,包括姓名、生日和电话号码,输入n(3≤n≤50)个朋友的信息,按年龄从大到小的顺序依次输出其信息。
【输入】
输入第一行为正整数n(3≤n≤50),表示朋友数量。
下面n行为朋友信息,每行包括姓名、生日和电话号码,以空格间隔。
【输出】
分行按年龄从大到小输出朋友信息。
【输入示例】
3
张三 19850403 13912345678
李四 19821020 0571-88123456
王五 19840619 13609876543
【输出示例】
李四 19821020 0571-88123456
王五 19840619 13609876543
张三 19850403 13912345678
【提示】
声明一个通讯录结构类型:
struct addressList {

char name[10];      /* 姓名 */
long birthday;        /* 生日 */
char phone[14];     /* 电话号码 */

};
使用qsort函数对年龄按从大到小排序。
【来源】
《程序设计基础——以C为例》第7章上机实验题1。
【参考答案】

#include <stdio.h>
#include <stdlib.h>
#define ARRAY_SIZE 50
struct addressList {
    char name[10];
    long birthday;
    char phone[14];
};
int comp(const void *p, const void *q) {
    return ((struct addressList *)p)->birthday - ((struct addressList *)q)->birthday;
}
int main(void) {
    struct addressList a[ARRAY_SIZE + 1];
    int i, n;
    scanf("%d", &n);
    for(i = 0; i < n; ++i) {
        scanf("%s%ld%s", a[i].name, &a[i].birthday, a[i].phone);
    }
    qsort(a, n, sizeof(struct addressList), comp);
    for(i = 0; i < n; ++i)
        printf("%s %ld %s\n", a[i].name, a[i].birthday, a[i].phone);
    return 0;
}

第6 题

【描述】
假设每个学生信息包括:姓名和3门课程的成绩。从键盘输入10个学生的数据,采用结构数组存储数据。输出3门课程的总平均分;输出每门课程分数最高的学生信息;按总分从高到低对这10个学生进行排序,并输出排序结果;输出平均分高于80分的学生信息。
【输入】
分行输入10个学生的数据,每行包括姓名和3门课程的成绩,以空格间隔。
【输出】
分行输出3门课程的总平均分、每门课程分数最高的学生信息、按总分从高到低输出学生信息以及平均分高于80分的学生信息。
【输入示例】
张三 88 99 78
李四 88 89 96
王五 67 78 89
刘六 45 56 67
钱七 23 43 78
孙八 88 96 98
高九 89 92 96
陈十 92 92 99
袁一 67 79 91
赵二 31 42 66
【输出示例】
76.73

陈十,92.00,92.00,99.00
张三,88.00,99.00,78.00
陈十,92.00,92.00,99.00

陈十,92.00,92.00,99.00
孙八,88.00,96.00,98.00
高九,89.00,92.00,96.00
李四,88.00,89.00,96.00
张三,88.00,99.00,78.00
袁一,67.00,79.00,91.00
王五,67.00,78.00,89.00
刘六,45.00,56.00,67.00
钱七,23.00,43.00,78.00
赵二,31.00,42.00, 66.00

陈十,92.00,92.00,99.00,94.33
孙八,88.00,96.00,98.00,94.00
高九,89.00,92.00,96.00,92.33
李四,88.00,89.00,96.00,91.00
张三,88.00,99.00,78.00,88.33
【提示】
声明一个学生信息结构类型:

struct student {
    char name[10];      /* 姓名 */
    double score[3];    /* 3门课程的成绩 */
    double total;          /* 总分 */
};

定义一个结构数组存储学生数据:

    #define ARRAY_SIZE 10           /* 学生人数 */
    struct student stud[ARRAY_SIZE];

定义计算3门课程总平均分的函数:

`double average(struct student *pStud, int n);`

定义输出每门课程分数最高的学生信息的函数:
void topStudentForEachSubject(struct student *pStud, int n);

定义输出平均分高于80分的学生信息的函数:
void studentGreaterThan80(struct student *pStud, int n);

上述函数中,参数pStud指向存储学生数据的结构数组,参数n表示学生人数。

使用qsort函数对总分按从高到低排序。

在主函数中输入学生数据,并调用上述相应的函数得到需要的结果。
【来源】
《程序设计基础——以C为例》第7章上机实验题2。
【参考答案】

#include <stdio.h>
#include <stdlib.h>
#define ARRAY_SIZE 10
/* 学生信息结构 */
struct student {
    char name[10];    /* 姓名 */
    double score[3];    /* 3门课程的成绩 */
    double total;
};
/* qsort比较函数,降序 */
int comp(const void *p, const void *q) {
    return ((struct student *)q)->total - ((struct student *)p)->total;
}
/* 求3门课程总平均分 */
double average(struct student *pStud, int n) {
    int i, j;
    double aver = 0;
    for(i = 0; i < n; ++i)
        for(j = 0; j < 3; ++j)
            aver += pStud[i].score[j];
    aver /= (n * 3);
    return aver;
}
/* 输出每门课程分数最高的学生信息 */
void topStudentForEachSubject(struct student *pStud, int n) {
    int i, j;
    struct student *pMax;
    for(i = 0; i < 3; ++i) {
        for(pMax = pStud, j = 0; j < n; ++j) {
            if(pMax->score[i] < (pStud + j)->score[i])
                pMax = pStud + j;
        }
        printf("%s,%.2f,%.2f,%.2f\n", pMax->name, pMax->score[0], pMax->score[1], pMax->score[2]);
    }
    printf("\n");
}
/* 输出平均分高于80分的学生信息 */
void studentGreaterThan80(struct student *pStud, int n) {
    struct student *pStart;
    double aver;
    for(pStart = pStud; pStart < pStud + n; ++pStart) {
        aver = (pStart->score[0] + pStart->score[1] + pStart->score[2]) / 3;
        if(aver > 80) {
            printf("%s,%.2f,%.2f,%.2f,%.2f\n", pStart->name, pStart->score[0], pStart->score[1], pStart->score[2], aver);
        }
    }
    printf("\n");
}
int main(void) {
    struct student stud[ARRAY_SIZE];     /* 存放学生数据的结构数组 */
    double averageAll;
    int i;
    for(i = 0; i < ARRAY_SIZE; ++i) {
        scanf("%s%lf%lf%lf", stud[i].name, &stud[i].score[0], &stud[i].score[1], &stud[i].score[2]);
        stud[i].total = stud[i].score[0] + stud[i].score[1] + stud[i].score[2];
    }
    /* 求3门课程总平均分 */
    averageAll = average(stud, ARRAY_SIZE);
    printf("%.2f\n\n", averageAll);
    /* 输出每门课程分数最高的学生信息 */
    topStudentForEachSubject(stud, ARRAY_SIZE);
    /* 使用qsort函数按总分从高到低排序 */
    qsort(stud, ARRAY_SIZE, sizeof(struct student), comp);
    for(i = 0; i < ARRAY_SIZE; ++i) {
         printf("%s,%.2f,%.2f,%.2f\n", stud[i].name, stud[i].score[0], stud[i].score[1], stud[i].score[2]);
    }
    printf("\n");
    /* 输出平均分高于80分的学生信息 */
    studentGreaterThan80(stud, ARRAY_SIZE);
    return 0;
}

第7 题

【描述】
本题要求编写程序,计算2个复数的和、差、积、商。
【输入】
输入在一行中按照“a1 b1 a2 b2”的格式给出2个复数c1=a1+b1*ic2=a2+b2*i的实部和虚部。题目保证c2不为0。
【输出】
分别在4行中按照“(a1+b1i) 运算符 (a2+b2i) = 结果”的格式顺序输出2个复数的和、差、积、商,数字精确到小数点后1位。如果结果的实部或者虚部为0,则不输出。如果结果为0,则输出0.0。
【输入示例】
2 3.08 -2.04 5.06
【输出示例】
(2.0+3.1i) + (-2.0+5.1i) = 8.1i
(2.0+3.1i) - (-2.0+5.1i) = 4.0-2.0i
(2.0+3.1i) * (-2.0+5.1i) = -19.7+3.8i
(2.0+3.1i) / (-2.0+5.1i) = 0.4-0.6i
【参考答案】

#include <stdio.h>
#include <math.h>
#define EPSILON 0.1
typedef struct {
    double realPart;
    double imaginaryPart;
} COMPLEX;    /* 复数类型 */ 
COMPLEX makeComplex(double r, double i);/* 构建复数 */ 
void printComplex(COMPLEX c);/* 输出复数 */ 
void printResult(COMPLEX c); /* 输出复数 */ 
COMPLEX addComplex(COMPLEX x, COMPLEX y);/* 复数加法 */ 
COMPLEX subComplex(COMPLEX x, COMPLEX y);/* 复数减法 */ 
COMPLEX mulComplex(COMPLEX x, COMPLEX y);/* 复数乘法 */ 
COMPLEX divComplex(COMPLEX x, COMPLEX y);/* 复数除法 */ 
int main(void) {
    double a1, b1, a2, b2;
    COMPLEX a, b, c;
    scanf("%lf%lf%lf%lf", &a1, &b1, &a2, &b2);
    a = makeComplex(a1, b1);
    b = makeComplex(a2, b2);
    /* 加法 */ 
    printComplex(a);
    printf(" + ");
    printComplex(b);
    printf(" = ");
    c = addComplex(a, b);
    printResult(c);
    /* 减法 */
    printComplex(a);
    printf(" - ");
    printComplex(b);
    printf(" = ");
    c = subComplex(a, b);
    printResult(c);
    /* 乘法 */
    printComplex(a);
    printf(" * ");
    printComplex(b);
    printf(" = ");
    c = mulComplex(a, b);
    printResult(c);
    /* 除法 */
    printComplex(a);
    printf(" / ");
    printComplex(b);
    printf(" = ");
    c = divComplex(a, b);
    printResult(c);
    return 0;
}
COMPLEX makeComplex(double r, double i) {
    COMPLEX temp;
    temp.realPart = r;
    temp.imaginaryPart = i;
    return temp;
}
void printComplex(COMPLEX c) {
    if(c.imaginaryPart >= 0)
        printf("(%.1f+%.1fi)", c.realPart, c.imaginaryPart);
    if(c.imaginaryPart < 0)
        printf("(%.1f%.1fi)", c.realPart, c.imaginaryPart);            
}
void printResult(COMPLEX c) {    
    if(c.realPart == 0 && c.imaginaryPart == 0)
        printf("%.1f\n", c.realPart);
    if(c.realPart && c.imaginaryPart > 0)
        printf("%.1f+%.1fi\n", c.realPart, c.imaginaryPart);
    if(c.realPart && c.imaginaryPart < 0)
        printf("%.1f%.1fi\n", c.realPart, c.imaginaryPart);
    if(c.realPart && c.imaginaryPart == 0)
        printf("%.1f\n", c.realPart);
    if(c.realPart == 0 && c.imaginaryPart)
        printf("%.1fi\n", c.imaginaryPart);
}
COMPLEX addComplex(COMPLEX x, COMPLEX y) {
    COMPLEX temp;
    temp.realPart = x.realPart + y.realPart;
    if(fabs(temp.realPart) < EPSILON)
        temp.realPart = 0; 
    temp.imaginaryPart = x.imaginaryPart + y.imaginaryPart;
    if(fabs(temp.imaginaryPart) < EPSILON)
        temp.imaginaryPart = 0; 
    return temp;
}
COMPLEX subComplex(COMPLEX x, COMPLEX y) {
    COMPLEX temp;
    temp.realPart = x.realPart - y.realPart;
    if(fabs(temp.realPart) < EPSILON)
        temp.realPart = 0; 
    temp.imaginaryPart = x.imaginaryPart - y.imaginaryPart;
    if(fabs(temp.imaginaryPart) < EPSILON)
        temp.imaginaryPart = 0; 
    return temp;
}
COMPLEX mulComplex(COMPLEX x, COMPLEX y) {
    COMPLEX temp;
    temp.realPart = x.realPart * y.realPart - x.imaginaryPart * y.imaginaryPart;
    if(fabs(temp.realPart) < EPSILON)
        temp.realPart = 0; 
    temp.imaginaryPart = x.realPart * y.imaginaryPart + x.imaginaryPart * y.realPart;
    if(fabs(temp.imaginaryPart) < EPSILON)
        temp.imaginaryPart = 0; 
    return temp;
}
COMPLEX divComplex(COMPLEX x, COMPLEX y) {
    COMPLEX temp;
    double denominator = y.realPart * y.realPart + y.imaginaryPart * y.imaginaryPart;
    temp.realPart = (x.realPart * y.realPart +
                     x.imaginaryPart * y.imaginaryPart) / denominator;
    if(fabs(temp.realPart) < EPSILON)
        temp.realPart = 0; 
    temp.imaginaryPart = (x.imaginaryPart * y.realPart -
                          x.realPart * y.imaginaryPart) / denominator;
    if(fabs(temp.imaginaryPart) < EPSILON)
        temp.imaginaryPart = 0; 
    return temp;
}

第8 题

【描述】
输入20个数,每个数都在1~10之间,求1~10中的众数(众数就是出现次数最多的数,如果存在一样多次数的众数,则输出值较小的)。
【输入】
输入20个1~10之间的数。
【输出】
输出20个1~10之间的数的众数。
【输入示例】
5 1 5 10 3 5 3 4 8 6 8 3 6 5 10 7 10 2 6 2
【输出示例】
5
【提示】
可以定义如下结构类型:

struct Data {  
    int count;    /* 出现次数 */  
    int value;     /* 值 */  
}; 

【参考答案】

#include <stdio.h>   
#include <stdlib.h>
struct Data {  
    int count;/* 出现次数 */   
    int value;/* 值 */   
}; 
int comp(const void *p, const void *q) {    
    struct Data *pp = (struct Data *)p;    
    struct Data *qq = (struct Data *)q;
    /* 次数不等的情况下,按次数降序排序 */
    /* 次数相等的情况下,按值升序排序 */     
    if(pp->count != qq->count)
        return qq->count - pp->count;    
    else if(pp->value != qq->value)   
        return pp->value - qq->value;    
}    
int main() {  
    int i, value;  
    struct Data data[11];  
    for(i = 0; i < 11; ++i) {
          data[i].count = 0;  
        data[i].value = i;  
    }  
    for(i = 0; i < 20; ++i) {  
        scanf("%d", &value);  
        ++data[value].count;  
    }
    qsort(data, 11, sizeof(data[0]), comp);
    printf("%d\n", data[0].value);  
    return 0;  
}  

第9 题

【描述】
本题要求编写程序,计算两个二维平面向量的和向量。
【输入】
输入在一行中按照“x1 y1 x2 y2”的格式给出两个二维平面向量V1=(x1, y1)和V2=(x2, y2)的分量。
【输出】
在一行中按照“(x, y)”的格式输出和向量,坐标输出小数点后1位(注意不能输出-0.0)。
【输入示例】
3.5 -2.7 -13.9 8.7
【输出示例】
(-10.4, 6.0)
【提示】
考虑运算后四舍五入的情况。
例如输入:0.0 0.0 -0.01 -0.01,结果:(0.0, 0.0)
【参考答案】

#include <stdio.h>
#include <math.h>
#define EPSILON 0.05 
struct Vector {
    double x;
    double y;
};
int main(void) {
    struct Vector v1, v2, v3;
    scanf("%lf%lf%lf%lf", &v1.x, &v1.y, &v2.x, &v2.y);
    v3.x = v1.x + v2.x;
    v3.y = v1.y + v2.y;
    if(fabs(v3.x) < EPSILON)
        v3.x = fabs(v3.x);
    if(fabs(v3.y) < EPSILON)
        v3.y = fabs(v3.y);
    printf("(%.1f, %.1f)\n", v3.x, v3.y);
    return 0;
}

第10 题

【描述】
某个科室的病房分为重症和普通,只有当病人的疾病严重程度超过了入住重症病房的最低严重值,才可以安排入住重症病房。
现在要求设计一个程序,给病人安排好病房。疾病的严重程度用0到10来表示,0表示小毛病,10表示非常严重。
【输入】
第一行输入病人的个数m(m < 50),以及安排住入重症病房的最低严重值a。
紧接着m行,每行表示病人编号(三位,用0补齐)及其疾病的严重程度(浮点数,1位小数)。
【输出】
每个病人的疾病严重程度都不一样。输出要求按照病人的严重程度输出住在重症病房里的病人的编号。
【注意】
如果当前所有病人的严重程度并不满足住在重症病房里,则输出“None.”。
【输入示例】
10 7.55
006 6.5
005 8.0
004 3.5
009 8.5
011 7.0
043 9.5
003 5.0
103 6.0
112 4.0
118 9.0
【输出示例】
043 9.5
118 9.0
009 8.5
005 8.0
【提示】
可以定义如下结构类型:

struct Person {
    int no;                 /* 病人的编号 */
    double num;       /* 病人病情严重程度 */
};

【参考答案】

#include <stdio.h>
#define ARRAY_SIZE 50
struct Person {
    int no;           /* 病人的编号 */
    double num;       /* 病人病情严重程度 */
};
int main(void) {
    struct Person p[ARRAY_SIZE];    /* 表示重症病人的结构数组 */
    int m;                    /* m个病人 */
    double a;                 /* 入住重症病房的最低严重值 */
    int n;                    /* 临时变量,表示当前输入的病人的编号 */
    double t;                 /* 临时变量,表示当前输入的病人的严重值 */
    int len = 0;              /* 表示当前已经遇到的重症病人的人数 */
    struct Person temp;
    int i, j, flag;
    scanf("%d%lf", &m, &a);
    for(i = 0; i < m; ++i) {         /* 读入m个人的信息并确定是否重症病人 */
        scanf("%d%lf", &n, &t);     /* 读入病人的编号和严重值 */
        if(t > a) {            /* 超过最低严重值 */
            p[len].no = n;
            p[len].num = t;
            len++;
        }
    }
    if(len == 0) {                 /* 假如没有重症病人 */
        printf("None.\n");
        return 0;
    }
    for(i = 1; i < len; ++i) {        /* 对重症病人按严重值降序排序 ,冒泡算法 */
        flag = 1;
        for(j = 0; j < len - i; ++j) {
            if(p[j].num < p[j + 1].num) {
                flag = 0;
                temp = p[j];
                p[j] = p[j + 1];
                p[j + 1] = temp;
            }
        }
        if(flag)
            break;
    }
    for(i = 0; i < len; ++i)           /* 按重症病人的严重值降序输出他们的信息 */
        printf("%03d %.1f\n", p[i].no, p[i].num);
    return 0;
}

练习12

第1 题

【描述】
输入10个整数,升序排序后存入文本文件example.txt中,文件每行存放5个整数,每行整数之间用一个空格间隔,每行最后一个整数后面没有空格。
【输入】
输入10个整数。
【输出】
文件example.txt。
【输入示例】
10 9 8 7 6 5 4 3 2 1
【输出示例】
文件example.txt,其中内容:
1 2 3 4 5
6 7 8 9 10
不需要在屏幕上显示信息。
【来源】
《程序设计基础——以C为例》第8章上机实验题1。
【参考答案】

#include <stdio.h>
#include <stdlib.h>
#define FILENAME "example.txt"
#define ARRAY_SIZE 10
int comp(const void *p, const void *q) {
    return (*(int *)p - *(int *)q);
}
int main(void) {
    FILE *outFile;
    int array[ARRAY_SIZE];
    int i, count = 1, x;
    outFile = fopen(FILENAME, "w");
    if(outFile == NULL) {
        exit(EXIT_FAILURE);
    }
    for(i = 0; i < ARRAY_SIZE; ++i)
        scanf("%d", &array[i]);
    qsort(array, ARRAY_SIZE, sizeof(int), comp);
    for(i = 0; i < ARRAY_SIZE; i++) {
        if(count++ % 5 == 0)
            fprintf(outFile, "%d\n", array[i]);
        else
            fprintf(outFile, "%d ", array[i]);
    }    
    fclose(outFile);
    return 0;
}

第2 题

【描述】
将一个明文文件plaintext.txt中的内容,按照一定的方法,对每个字符加密后存放到另一个密文文件ciphertext.txt中。
【输入】
文件plaintext.txt。
【输出】
文件ciphertext.txt。
【输入示例】
文件plaintext.txt,其中内容:
Welcome to C!
【输出示例】
文件ciphertext.txt,其中内容:
Ygneqog"vq"E#
不需要在屏幕上显示信息。
【提示】
这里采用一种简单的加密方法,将每个字符的编码加2。
明文文件plaintext.txt已经存在。本地调试时,需要自己预先建立文件plaintext.txt。在Windows下,可以使用记事本。
【来源】
《程序设计基础——以C为例》第8章上机实验题5。
【参考答案】

#include <stdio.h>
#include <stdlib.h>
#define CODING 2
#define FILENAME1 "plaintext.txt"
#define FILENAME2 "ciphertext.txt"
int main(void) {
    FILE *fp1, *fp2;
    char ch;
    if((fp1 = fopen(FILENAME1, "r")) == NULL) {
        exit(EXIT_FAILURE);
    }
    if((fp2 = fopen(FILENAME2, "w")) == NULL) {
        exit(EXIT_FAILURE);
    }
    ch = fgetc(fp1);
    while(!feof(fp1)) {
        ch += CODING;
        fputc(ch, fp2);
        ch = fgetc(fp1);
    }
    fclose(fp1);
    fclose(fp2);
    return 0;
}

第3 题

【描述】
建立一个学生基本信息结构,包括学号、姓名以及语文、数学、英语3门课程的成绩,输入n个(0≤n≤100)学生的基本信息,计算每个学生3门课程的总分和平均分(保留2位小数),并写到文本文件student.txt中。
【输入】
输入第一行为正整数n。
下面n行,每行一个学生信息,学号、姓名和成绩之间以空格间隔。
【输出】
文件student.txt。
【输入示例】
5
100101 张三 78 83 75
100102 李四 76 80 77
100103 王五 87 83 76
100104 刘六 45 56 67
100105 钱七 23 43 78
【输出示例】
文件student.txt,其中内容:
100101 张三 78 83 75 236 78.67
100102 李四 76 80 77 233 77.67
100103 王五 87 83 76 246 82.00
100104 刘六 45 56 67 168 56.00
100105 钱七 23 43 78 144 48.00
不需要在屏幕上显示信息。
【来源】
《程序设计基础——以C为例》第8章上机实验题4。
【参考答案】

#include <stdio.h>
#include <stdlib.h>
#define ARRAY_SIZE 100
struct student {
    int num;
    char name[10];
    int score[3];
};
int main(void) {
    FILE *fp;
    struct student s[ARRAY_SIZE];/* 存放学生基本信息的结构数组 */
    int total;/* 存放总分 */
    double average;/* 存放平均分 */
    int i, n;
    if((fp = fopen("student.txt", "w")) == NULL) {
        exit(EXIT_FAILURE);
    }
    scanf("%d", &n);
    for(i = 0; i < n; ++i) {
        scanf("%d%s%d%d%d", &s[i].num, s[i].name, &s[i].score[0], &s[i].score[1], &s[i].score[2]);
        total = s[i].score[0] + s[i].score[1] + s[i].score[2];
        average = total / 3.0;
    fprintf(fp, "%d %s %d %d %d %d %.2f\n", s[i].num, s[i].name, s[i].score[0], s[i].score[1], s[i].score[2], total, average);
    }
    fclose(fp);
    return 0;
}

第4 题

【描述】
处理日志文件,日志文件的储存格式为“年/月/日 时:分:秒 用户名 操作”。
日志文件有多条记录:

2015/4/218:00:33 37c3b6b58c6ac3 LOGIN
2015/4/218:15:35 11734e186f24fe4c LOGIN
2015/4/218:34:57 9f3cf331d19a9f LOGIN
2015/4/219:00:29 389bcca2159f5de7 LOGIN
2015/4/219:08:29 c3bde693fdb3c3d LOGIN
……

可以下载日志文件:
鼠标右键另存为
【输入】
日志文件log.txt。(该文件已经存在,无需自己创建)
【输出】
日志文件中记录数。
【输入示例】

【输出示例】
1234
【提示】
输出示例只是格式说明,并非正确答案。
【参考答案】

#include <stdio.h>
#include <stdlib.h>
#define MAX_LINE 100
int main(void) {
    FILE *fp;
    int count = 0;
    char buffer[MAX_LINE];
    if((fp = fopen("log.txt", "r")) == NULL)
        exit(EXIT_FAILURE);
    while(fgets(buffer, MAX_LINE, fp) != NULL)
        ++count;
    fclose(fp);
    printf("%d\n", count);
    return 0;
}

第5 题

【描述】
处理日志文件,日志文件的储存格式为“年/月/日 时:分:秒 用户名 操作”。
日志文件有多条记录:

2015/4/218:00:33 37c3b6b58c6ac3 LOGIN
2015/4/218:15:35 11734e186f24fe4c LOGIN
2015/4/218:34:57 9f3cf331d19a9f LOGIN
2015/4/219:00:29 389bcca2159f5de7 LOGIN
2015/4/219:08:29 c3bde693fdb3c3d LOGIN
……

可以下载日志文件:
鼠标右键另存为
【输入】
日志文件log.txt。(该文件已经存在,无需自己创建)
【输出】
日志文件中活跃用户的数量。
【输入示例】
无。
【输出示例】
123
【提示】
输出示例只是格式说明,并非正确答案。
活跃用户指的是在日志文件中有过操作的用户,记得把重复出现的用户去掉。
【参考答案】

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(void) {
    FILE *fp;
    int year, month, day, hour, minute, second;
    char id[20], ids[600][20], operation[10];
    int i, user_count = 0, found;
    if((fp = fopen("log.txt", "r")) == NULL)
        exit(EXIT_FAILURE);
    while(!feof(fp)) {
        fscanf(fp, "%d/%d/%d %d:%d:%d %s %s", 
              &year, &month, &day, &hour, &minute, &second, id, operation);
        found = -1;
        for(i = 0; i < user_count; ++i) {
            if(strcmp(id, ids[i]) == 0) {
                found = i;
                break;
            }
        }
        if(found == -1)
            strcpy(ids[user_count++], id);
    }
    fclose(fp);
    printf("%d\n", user_count);
    return 0;
}

第6 题

【描述】
处理日志文件,日志文件的储存格式为“年/月/日 时:分:秒 用户名 操作”。
日志文件有多条记录:

2015/4/218:00:33 37c3b6b58c6ac3 LOGIN
2015/4/218:15:35 11734e186f24fe4c LOGIN
2015/4/218:34:57 9f3cf331d19a9f LOGIN
2015/4/219:00:29 389bcca2159f5de7 LOGIN
2015/4/219:08:29 c3bde693fdb3c3d LOGIN
……

可以下载日志文件:
鼠标右键另存为
【输入】
日志文件log.txt。(该文件已经存在,无需自己创建)
【输出】
生成文件times.txt,里面存放活跃用户的在线时长。
不需要在屏幕上显示信息。
【输入示例】

【输出示例】
文件times.txt,注意:这里只给出了其中部分内容。
37c3b6b58c6ac 31887052
11734e186f24fe4c 2088931
9f3cf331d19a9f 2147511
389bcca2159f5de 71398643
c3bde693fdb3c3d 1297166
……
【提示】
活跃用户指的是在日志文件中有过操作的用户,记得把重复出现的用户去掉。
在线时长单位为秒。为简单起见,日志文件中日期都为同一年的。
【参考答案】

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* 时间类型的结构定义 */
struct Time_t {
        int year, month, day;
    int hour, minute, second;
};
/* 计算时长的函数声明 */
int timeDifference(struct Time_t, struct Time_t);
int main(void) {
    FILE *fp;
    int user_count = 0;            /* 用户数,初始值为0 */
    char ids[600][20];            /* 记录所有的编号 */
    int online[600];            /* 在线状态 */
    struct Time_t last_on[600];        /* 上次登录时间 */
    int secs[600];                /* 累计在线秒数 */
    struct Time_t t;
    char id[20], operation[10];
    int i, found;
    if((fp = fopen("log.txt", "r")) == NULL)
        exit(EXIT_FAILURE);
    while(!feof(fp)) {
        fscanf(fp, "%d/%d/%d %d:%d:%d %s %s", 
              &t.year, &t.month, &t.day, &t.hour, &t.minute, &t.second, 
              id, operation);
        /* 线性查找 */
        found = -1;
        for(i = 0; i < user_count; ++i)
            if(strcmp(id, ids[i]) == 0) {
                                found = i;
                break;
            }
        /* 如果没找到,说明是新用户,记录 */
        if(found == -1) {
            strcpy(ids[user_count], id);
            /* 记录新用户的登陆状态 */
            if(strcmp(operation, "LOGIN") == 0) {
                online[user_count] = 1;
                last_on[user_count] = t;
            }
            else
                online[user_count] = 0;
            secs[user_count] = 0;
            ++user_count;
        }
        /* 否则,修改登录状态,计算登录时长 */
        else {
            if(strcmp(operation, "LOGIN") == 0) {
                if(!online[found]) {
                    online[found] = 1;
                    last_on[found] = t;
                }
            }
            else {
                if(online[found]) {
                    online[found] = 0;
                    /* 调用函数,计算两个时刻之差 */
                    secs[found] += timeDifference(last_on[found], t);
                }
            }
        }
    }
    fclose(fp);
    /* 输出每个用户的在线时长 */
    if((fp = fopen("times.txt", "w")) == NULL)
        exit(EXIT_FAILURE);
    for(i = 0; i < user_count; ++i)
        fprintf(fp, "%s %d\n", ids[i], secs[i]);
    fclose(fp);
    return 0;
}
/* 计算时间差,日期在同一年 */
int timeDifference(struct Time_t t1, struct Time_t t2) {
    int days[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    int day_count = t2.day - t1.day;
    int i, result;
    for(i = t1.month; i < t2.month; ++i)
        day_count += days[i - 1];
    result = day_count * 60 * 60 * 24;
    result += (t2.hour - t1.hour) * 60 * 60;
    result += (t2.minute - t1.minute) * 60;
    result += (t2.second - t1.second);
    return result;
}

第7 题

【描述】
输入一篇英文文章,求出现次数前三名的字母,不区分大小写(即出现A也计入出现a的次数中),按照次数由大到小输出,如果出现次数一样,按字典顺序输出。其它字符不予考虑。
附带说明:英文中,每个字母出现的频率是不一样的,在破译英文密码时,尤其是凯撒密码,统计每个字母出现的频率有着重要意义。
可以下载英文文章:
鼠标右键另存为
【输入】
英文文章news.txt。(该文件已经存在,无需自己创建)
【输出】
以如下格式:
字母:出现次数
显示出现次数前三名的字母和出现次数。
【输入示例】
无。
【输出示例】
a:xxx
b:xx
c:xx
【提示】
输出示例只是格式说明,并非正确答案。
【参考答案】

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define MAX_LINE 1000
struct Letter {
    int count; /* 次数 */ 
    char ch;   /* 字母 */ 
};
int comp(const void *p, const void *q) {    
    struct Letter *pp = (struct Letter*)p;    
    struct Letter *qq = (struct Letter*)q;
    /* 按次数降序排序 */ 
    if(pp->count != qq->count)
        return qq->count - pp->count;    
}
int main(void) {
    FILE *fp;
    struct Letter counts[26];
    char line[MAX_LINE];
    int i;
    for(i = 0; i < 26; ++i) {
        counts[i].count = 0;
        counts[i].ch = (char)('a' + i);
    }
    if((fp = fopen("news.txt", "r")) == NULL)
        exit(EXIT_FAILURE);
    while(fgets(line, MAX_LINE, fp) != NULL) {
        for(i = 0; i < strlen(line); ++i) {
            if(isalpha(line[i])) {
                if(isupper(line[i]))
                    line[i] = tolower(line[i]);
                ++counts[line[i] - 'a'].count;
            }
        }
    }
    qsort(counts, 26, sizeof(counts[0]), comp);
    for(i = 0; i < 3; ++i)
        printf("%c:%d\n", counts[i].ch, counts[i].count);
    return 0;
}

第8 题

【描述】
以二进制方式打开图片文件并读取该文件中的第 13(从1开始计数,后同),49, 80 个字节处的值,求这3个二进制数按位异或的结果(16进制表示)。
可以鼠标右键另存为下载图片文件:

【输入】
图片文件image.jpg。(该文件已经存在,无需自己创建)
【输出】
第 13(从1开始计数,后同),49, 80个字节处3个二进制数按位异或的结果(16进制表示)。
【输入示例】
无。
【输出示例】
a9
【提示】
输出示例只是格式说明,并非正确答案。
【参考答案】

#include <stdio.h>
#include <stdlib.h>
int main(void) {
    FILE *fp;
    char byte1, byte2, byte3;
    if((fp = fopen("image.jpg", "rb")) == NULL)
        exit(EXIT_FAILURE);    
    fseek(fp, 12L, SEEK_SET);
    fread(&byte1, 1, 1, fp);
    fseek(fp, 48L, SEEK_SET);
    fread(&byte2, 1, 1, fp);
    fseek(fp, 79L, SEEK_SET);
    fread(&byte3, 1, 1, fp);
    printf("%x\n",(byte1 ^ byte2 ^ byte3) & 0x000000ff);
    return 0;
}

第9 题

【描述】
给定文件hours.txt,其中包含每个员工工作时间的记录。每一行表示一周的工作时间。每周有7天,所以每行最多有7个数字。规定每周从周一开始,文件中的每一行都是从周一的工作小时数开始,后面是周二,等等,周日的数字放在这一行的最后。每行中的数字可以少于7个,因为员工并不是每天都要工作。下面是文件hours.txt的内容:

8 8 8 8 8
8 4 8 4 8 4 4
8 4 8 4 8
3 0 0 8 6 4 4
8 8
0 0 8 8
8 8 4 8 4

编写一个程序从输入文件中读取数据,计算并报告每行和每列的总和。每行的总和表示该员工每周工作的小时数。每列的总和表示员工周一、周二等每天工作的累计小时数。最后输出总的小时数。针对上述文件hours.txt的输出结果见【输出示例】。
【输入】
文件hours.txt。(该文件已经存在,无需自己创建)
注意:本地调试程序时,则要求自己预先建立好plaintext.txt文件。在Windows下,可以使用记事本。
【输出】
员工每周工作的小时数。
员工周一、周二等每天工作的累计小时数。
最后输出总的小时数。
【输入示例】
无。
【输出示例】
Total hours = 40
Total hours = 40
Total hours = 32
Total hours = 25
Total hours = 16
Total hours = 16
Total hours = 32

Mon hours = 43
Tue hours = 32
Wed hours = 36
Thu hours = 40
Fri hours = 34
Sat hours = 8
Sun hours = 8
Total hours = 201
【参考答案】

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define DAYS 7
#define MAX_LINE 100
void process(FILE *inFile);
/* 将字符串line分离为数字存放在数组numbers中,并返回numbers中实际元素个数 */
int transferFrom(int numbers[], char *line);
/* 返回数组numbers的和(某员工每周工作时间的小时数)*/
int sum(int numbers[], int size);
/* 统计员工每周每天工作累计小时数 */
void addTo(int total[], int numbers[]);
/* 输出员工每周每天工作累计小时数和总的小时数 */ 
void print(int total[]);
int main(void) {
    FILE *inFile;
    inFile = fopen("hours.txt", "r");
    if(inFile == NULL)
        exit(EXIT_FAILURE);
    process(inFile);
    return 0;
}
void process(FILE *inFile) {
    int total[DAYS] = {0};        /* 员工每周每天工作累计小时数 */
    int numbers[DAYS] = {0};    /* 某员工每周工作时间 */    
    int size;
    char line[MAX_LINE]; 
    while(fgets(line, MAX_LINE, inFile) != NULL) {
        size = transferFrom(numbers, line);
        printf("Total hours = %d\n", sum(numbers, size));
        addTo(total, numbers);
    }
    printf("\n");
    print(total);
}
int transferFrom(int numbers[], char *line) {
    int i = 0, j;
    char *p;
    p = strtok(line, " ");
    while(p) {
        numbers[i++] = atoi(p);
        p = strtok(NULL, " ");
    }
    /* 每行数据个数不同,Number数组后面没有数据的元素值设置为0 */
    for(j = i; j < DAYS; ++j)
        numbers[j] = 0;
    return i;
}
int sum(int numbers[], int size) {
    int i, s = 0;
    for(i = 0; i < size; ++i)
        s += numbers[i];
    return s;
}
void addTo(int total[], int numbers[]) {
    int i;
    for(i = 0; i < DAYS; ++i)
        total[i] += numbers[i];
}
void print(int total[]) {
    char *dayNames[DAYS] = {"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"};
    int i, s = 0;
    for(i = 0; i < DAYS; ++i) {
        printf("%s hours = %d\n", dayNames[i], total[i]);
        s += total[i];
    }
    printf("Total hours = %d\n", s); 
}

第10 题

【描述】
需要计算一些学生的加权平均分。给定文件gpa.dat,文件中每个学生的信息都由两行内容组成。第一行是学生姓名,第二行是他几门课的成绩。下面是某个输入文件gpa.dat的内容:

Zhang San
3 2.8 4 3.9 3 3.1
Li Si
3 3.9 3 4.0 4 3.9
Wang Wu
2 4.0 3 3.6 4 3.8 1 2.8
Liu Liu
3 3.0 4 2.9 3 3.2 2 2.5

例如,张三(Zhang San)同学:第一门课,学分3,成绩2.8;第二门课,学分4,成绩3.9;第三门课,学分3,成绩3.1。

总平均分等于学分乘以成绩,加权平均分等于总平均分除以总学分数。加权平均分最低0.0,最高4.0。
【输入】
文件gpa.dat。(该文件已经存在,无需自己创建)
注意:本地调试程序时,则要求自己预先建立好gpa.dat文件。在Windows下,可以使用记事本。
【输出】
在屏幕上显示每个学生的加权平均分以及加权平均分的最大和最小值。
【输入示例】
文件gpa.dat,其中内容:
Zhang San
3 2.8 4 3.9 3 3.1
Li Si
3 3.9 3 4.0 4 3.9
Wang Wu
2 4.0 3 3.6 4 3.8 1 2.8
Liu Liu
3 3.0 4 2.9 3 3.2 2 2.5
【输出示例】
GPA for Zhang San = 3.33
GPA for Li Si = 3.93
GPA for Wang Wu = 3.68
GPA for Liu Liu = 2.93
max GPA = 3.93
min GPA = 2.93
【参考答案】

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void process(FILE *fp);
double processGrades(char *grades);
int main(void) {
    FILE *fp;
    if((fp = fopen("gpa.dat", "r")) == NULL)
       exit(EXIT_FAILURE);
    process(fp);
    return 0;
}
void process(FILE *fp) {
    double max = 0.0;
    double min = 4.0;
    char name[20], grades[100];
    double gpa;
    while (!feof(fp)) {
        fgets(name, 20, fp);
        fgets(grades, 100, fp);
        gpa = processGrades(grades);
        name[strlen(name) - 1] = '\0';/* 消除尾部换行符 */
        printf("GPA for %s = %.2f\n", name, gpa);
        if (gpa > max)
            max = gpa;
        if (gpa < min)
            min = gpa;
    }
    printf("max GPA = %.2f\n", max);
    printf("min GPA = %.2f\n", min);
}
double processGrades(char *grades) {
    double totalQualityPoints = 0.0;    /* 总平均分 */
    double totalUnits = 0.0;        /* 总学分数 */
    double value[100];
    char *p;
    int i = 0, j;
    p = strtok(grades, " ");
    while(p) {
        value[i++] = atof(p);
        p = strtok(NULL, " ");
    }
    for(j = 0; j < i; j += 2) {
            totalUnits += value[j];
            totalQualityPoints += value[j] * value[j + 1];
        }
    if(totalUnits == 0.0)
        return 0.0;
    else
        return totalQualityPoints / totalUnits;
}

至此就全部结束了

最后修改:2020 年 06 月 19 日 01 : 49 PM
如果觉得我的文章对你有用,请随意赞赏