已完结:《C语言程序设计(第4版)》谭浩强著,清华大学出版社,课后习题答案

第一章:

 1.1

#include <stdio.h>

int main() {
    // 输出指定信息
    printf("****************\n");
    printf("   Very good!\n");
    printf("****************\n");

    return 0;
}

1.2

#include <stdio.h>

int main() {
    float a, b, c;

    // 输入三个值
    printf("请输入三个数 (a, b, c):");
    scanf("%f %f %f", &a, &b, &c);

    // 判断最大值并输出
    if (a >= b && a >= c) {
        printf("最大值是: %.2f\n", a);
    } else if (b >= a && b >= c) {
        printf("最大值是: %.2f\n", b);
    } else {
        printf("最大值是: %.2f\n", c);
    }

    return 0;
}

1.3

自觉完成 ^_^

1.4

即1.1 1.2 ^_^ 

第二章:

2.1 

#include <stdio.h>
#include <math.h>

int main() {
    double r = 0.1;  // 年增长率 10%
    int n = 10;      // 年数 10年
    double P;

    // 计算10年后的增长倍数
    P = pow((1 + r), n);

    // 计算增长的百分比
    double growth_percentage = (P - 1) * 100;

    // 输出结果
    printf("10年后我国国民生产总值与现在相比增长了 %.2f%%\n", growth_percentage);

    return 0;
}

2.2 

#include <stdio.h>
#include <math.h>

// 计算定期存款本息和的函数
double calculate_interest(double P, double r, int n) {
    return P * pow((1 + r), n);
}

// 计算活期存款本息和的函数(每季度结算一次)
double calculate_current_interest(double P, double r, int n) {
    return P * pow((1 + r / 4), 4 * n);  // 每年4个季度,存5年共20个季度
}

int main() {
    double P = 1000.0;  // 初始本金
    double result;

    // (1) 一次存5年期,年利率5.85%
    double r1 = 0.0585;  // 5年期年利率
    result = calculate_interest(P, r1, 5);
    printf("一次存5年期的本息和: %.2f 元\n", result);

    // (2) 先存2年期,再存3年期
    double r2_1 = 0.0468;  // 2年期年利率
    double r2_2 = 0.054;   // 3年期年利率
    result = calculate_interest(P, r2_1, 2);  // 先存2年
    result = calculate_interest(result, r2_2, 3);  // 再存3年
    printf("先存2年期,再存3年期的本息和: %.2f 元\n", result);

    // (3) 先存3年期,再存2年期
    double r3_1 = 0.054;   // 3年期年利率
    double r3_2 = 0.0468;  // 2年期年利率
    result = calculate_interest(P, r3_1, 3);  // 先存3年
    result = calculate_interest(result, r3_2, 2);  // 再存2年
    printf("先存3年期,再存2年期的本息和: %.2f 元\n", result);

    // (4) 存1年期,连续存5次,每年年利率4.14%
    double r4 = 0.0414;  // 1年期年利率
    result = P;
    for (int i = 0; i < 5; i++) {
        result = calculate_interest(result, r4, 1);  // 每年存1年期
    }
    printf("存1年期,连续存5次的本息和: %.2f 元\n", result);

    // (5) 活期存款,年利率0.72%,每季度结算一次
    double r5 = 0.0072;  // 活期存款年利率
    result = calculate_current_interest(P, r5, 5);  // 5年活期存款
    printf("活期存款的本息和: %.2f 元\n", result);

    return 0;
}

2.3 

#include <stdio.h>

int main() {
    char c1 = 'C', c2 = 'h', c3 = 'i', c4 = 'n', c5 = 'a';

    // 加密操作,每个字母向后移4位
    c1 += 4;
    c2 += 4;
    c3 += 4;
    c4 += 4;
    c5 += 4;

    // 输出加密后的结果
    printf("%c%c%c%c%c\n", c1, c2, c3, c4, c5);

    return 0;
}

2.4 

修正后的代码

#include <stdio.h>

int main() {
    int num1, num2;  // 使用更有意义的变量名

    num1 = 97;
    num2 = 98;

    printf("第一个数是 %d\n", num1);
    printf("第二个数是 %d\n", num2);

    return 0;
}


问题解答
(1) 运行时会输出什么信息?为什么?

修正后的代码会输出:
第一个数是 97
第二个数是 98
因为我们给num1和num2分别赋值为97和98,然后使用%d格式符将它们作为整数输出。

(2) 如果将程序第4、5行改为c1=289; c2=322; 运行时会输出什么信息?为什么?

如果将num1和num2的值改为289和322,那么输出结果也会相应地变为:
第一个数是 289
第二个数是 322
printf函数会根据格式字符串中的%d来读取对应的整数变量的值,并将它们按照指定的格式输出。

第三章: 

3.1 

1.表达式和表达式语句的概念

表达式:是一组运算符和操作数的组合,用于计算一个值。它不表示一个完整的语句,需要在语句中使用。
例如:a + b, x++, (a > b) ? a : b。
表达式语句:是一个以分号结尾的表达式。它既是一个表达式,又是一个完整的语句。表达式语句的目的是计算表达式的值,并作为一条独立的语句执行。
例如:x = 10;, sum += i;。

2.C语言为什么要设置表达式语句?

简化代码: 表达式语句可以将简单的赋值操作或计算直接写在语句中,使得代码更加简洁。
提高效率: 某些情况下,表达式语句的执行效率可能更高,尤其是对于简单的赋值操作。
增强表达能力: 表达式语句可以结合各种运算符和函数调用,实现复杂的计算和赋值操作。

3.什么时候用表达式,什么时候用表达式语句?

表达式:
用在赋值语句的右侧:y = x + 1;
用在条件判断中:if (a > b)
用在函数的参数中:printf("%d", x);
用在返回值中:return x + y;

表达式语句:
进行简单的赋值操作:count++;
调用函数:printf("Hello, world!\n");
执行自增自减运算:i++;
进行简单的计算:sum = a + b;

3.2 

1. 灵活性与可扩展性
设备无关性: 通过函数的形式,可以很容易地将输入输出功能扩展到不同的设备上。比如,可以编写函数将数据输出到屏幕、文件、网络等。
自定义格式: 函数可以灵活地定义输入输出的格式,满足各种不同的需求。例如,printf函数的格式控制字符串可以实现各种各样的输出格式。
错误处理: 函数可以返回错误码或通过其他方式来表示输入输出操作是否成功,方便程序进行错误处理。

2. 模块化与复用
代码复用: 将输入输出功能封装成函数,可以方便地重复使用,提高代码的复用性。
模块化设计: 将输入输出功能与主程序逻辑分离,使得程序结构更加清晰,便于维护和调试。

3. 标准化与可移植性
标准库: C语言的输入输出函数是标准库的一部分,不同的编译器都实现了这些函数,保证了程序的可移植性。
统一接口: 标准化的函数接口使得程序员更容易学习和使用输入输出功能。

4. 效率考虑
优化空间: 将输入输出功能作为函数,编译器可以针对不同的输入输出操作进行优化,提高程序的运行效率。

3.3 

a=3 b=7 8.5 71.82 A a

3.4 

10 20 A a 1.5 -3.75 67.8

 3.5

#include <stdio.h>
#define PI 3.14159

int main() {
    double r, h;

    printf("请输入圆的半径和圆柱的高(用空格隔开): ");
    scanf("%lf %lf", &r, &h);

    // 计算各种值
    double circumference = 2 * PI * r;
    double circleArea = PI * r * r;
    double sphereSurfaceArea = 4 * PI * r * r;
    double sphereVolume = (4.0 / 3) * PI * r * r * r;
    double cylinderVolume = PI * r * r * h;

    // 输出结果,保留两位小数
    printf("圆的周长为: %.2lf\n", circumference);
    printf("圆的面积为: %.2lf\n", circleArea);
    printf("圆球的表面积为: %.2lf\n", sphereSurfaceArea);
    printf("圆球的体积为: %.2lf\n", sphereVolume);
    printf("圆柱的体积为: %.2lf\n", cylinderVolume);

    return 0;
}

3.6 

#include <stdio.h>

int main() {
    float fahrenheit, celsius;

    printf("请输入华氏温度: ");
    scanf("%f", &fahrenheit);

    // 计算摄氏温度
    celsius = 5.0 * (fahrenheit - 32) / 9;

    // 输出结果,保留两位小数
    printf("%.2f华氏度等于%.2f摄氏度。\n", fahrenheit, celsius);

    return 0;
}

 3.7

1. 变量 c1 和 c2 应定义为字符型或整型?
通常定义为字符型: 由于 getchar 函数是用来读取单个字符的,因此 c1 和 c2 变量通常定义为字符型(char),这样可以更准确地表示单个字符。
也可以定义为整型: 虽然字符型变量本质上也是用整数来表示字符的ASCII码,但将字符变量定义为整型可能会导致一些意想不到的结果,例如在某些操作中可能出现符号扩展。

2. 要求输出 c1 和 c2 值的 ASCII 码,应如何处理?
使用 printf 函数: printf 函数功能更强大,可以格式化输出。我们可以使用 %d 格式说明符来输出字符对应的 ASCII 码。
putchar 函数只能输出单个字符,无法直接输出 ASCII 码。

3. 整型变量与字符变量是否在任何情况下都可以互相代替?
一般情况下不能: 虽然字符型变量本质上也是用整数来表示字符的 ASCII 码,但字符型变量和整型变量在内存中的存储方式、参与运算的方式等方面存在差异。
特殊情况下可以: 在某些特定的情况下,可以将字符型变量赋值给整型变量,或者将整型变量(其值在字符的 ASCII 码范围内)赋值给字符型变量。但这种做法并不推荐,容易导致代码的可读性降低,并且可能产生一些意想不到的结果。

 第四章:

 

4.1 

1. 算术运算符
算术运算符用于执行基本的数学运算,就像我们在纸上进行计算一样。

加法运算符(+): 将两个数相加。例如:a + b
减法运算符(-): 从第一个数中减去第二个数。例如:a - b
乘法运算符(*): 将两个数相乘。例如:a * b
除法运算符(/): 将第一个数除以第二个数。例如:a / b
取模运算符(%): 求两个数相除的余数。例如:a % b (这个运算符在求余数时非常有用)

2. 关系运算符
关系运算符用于比较两个值的大小,并返回一个布尔值(真或假)。

等于运算符(==): 判断两个值是否相等。例如:a == b
不等于运算符(!=): 判断两个值是否不相等。例如:a != b
大于运算符(>): 判断第一个值是否大于第二个值。例如:a > b
小于运算符(<): 判断第一个值是否小于第二个值。例如:a < b
大于等于运算符(>=): 判断第一个值是否大于等于第二个值。例如:a >= b
小于等于运算符(<=): 判断第一个值是否小于等于第二个值。例如:a <= b

3. 逻辑运算符
逻辑运算符用于对多个条件进行组合,并返回一个布尔值。

逻辑与运算符(&&): 只有当两个条件都为真时,结果才为真。例如:a > 0 && b < 10 (表示a大于0并且b小于10)
逻辑或运算符(||): 只要有一个条件为真,结果就为真。例如:a == 0 || b == 0 (表示a等于0或者b等于0)
逻辑非运算符(!): 对一个条件取反。例如:!a (如果a为真,则!a为假;如果a为假,则!a为真)

4.2 

C语言中的真假表示
在C语言中,并没有专门的布尔类型(如其他编程语言中的 true 和 false)来表示真假。而是用数值来表示:

0: 表示假(false)
非0: 表示真(true),通常用1来表示
系统如何判断真假
C语言在进行条件判断时,会将非零值视为真,将0视为假。例如,在 if 语句中,如果条件表达式的值为非0,则执行 if 语句块。

4.3 

表达式分析:

(1) a+b>c&&b=-c

a+b>c 即 3+4>5,为真。
b=-c,将-5赋值给b,但由于前面部分已经为真,且&&是逻辑与,所以后面部分不再计算。
结果:真

(2) a/b+c&&b-c

a/b+c 即 3/4+5,整数除法结果为0,加上5得到5。
b-c 即 4-5,为-1。
结果:真 (因为任何非零值都表示真)

(3) !(a>b)&&!cl1

!(a>b) 即 !(3>4),为真。
!cl1 的值无法确定,因为cl1未定义。
结果:无法确定,因为依赖于cl1的值。

(4) !(x=a)&&(y=b)&&0

x=a 将3赋值给x。
y=b 将4赋值给y。
!(x=a) 始终为假,因为赋值表达式的结果为赋值的值,即3,为真,取反后为假。
0 始终为假。
结果:假

(5) !(a+b)+c-1&& b+c/2

!(a+b) 即 !(3+4),为假。
!(a+b)+c-1 计算结果为4。
b+c/2 即 4+5/2,整数除法结果为2,加上4为6。
结果:真 (因为4和6都是非零值)

 4.4

4.5 

#include <stdio.h>

int main() {
    int a, b, c, max;

    printf("请输入三个整数:");
    scanf("%d %d %d", &a, &b, &c);

    // 找到最大值
    max = a;  // 初始将最大值设为a
    if (b > max) {
        max = b;
    }
    if (c > max) {
        max = c;
    }

    printf("最大的数是:%d\n", max);

    return 0;
}

4.6 

4.7 

#include <stdio.h>

int main() {
    int num, count = 0, digit;

    printf("请输入一个不超过5位的正整数:");
    scanf("%d", &num);

    // 1. 求出位数
    int temp = num;
    while (temp > 0) {
        temp /= 10;
        count++;
    }
    printf("该数是%d位数\n", count);

    // 2. 分别输出每一位数字
    temp = num;
    printf("每一位数字:");
    while (temp > 0) {
        digit = temp % 10;
        printf("%d ", digit);
        temp /= 10;
    }
    printf("\n");

    // 3. 按逆序输出各位数字
    printf("逆序输出:");
    while (count > 0) {
        digit = num % 10;
        printf("%d", digit);
        num /= 10;
        count--;
    }
    printf("\n");

    return 0;
}

4.8 

1. 使用 if 语句

#include <stdio.h>

int main() {
    double profit, bonus;

    printf("请输入企业的年利润:");
    scanf("%lf", &profit);

    if (profit <= 100000) {
        bonus = profit * 0.1;
    } else if (profit <= 200000) {
        bonus = 100000 * 0.1 + (profit - 100000) * 0.075;
    } else if (profit <= 400000) {
        bonus = 100000 * 0.1 + 100000 * 0.075 + (profit - 200000) * 0.05;
    } else if (profit <= 600000) {
        bonus = 100000 * 0.1 + 100000 * 0.075 + 200000 * 0.05 + (profit - 400000) * 0.03;
    } else if (profit <= 1000000) {
        bonus = 100000 * 0.1 + 100000 * 0.075 + 200000 * 0.05 + 200000 * 0.03 + (profit - 600000) * 0.015;
    } else {
        bonus = 100000 * 0.1 + 100000   
 * 0.075 + 200000 * 0.05 + 200000 * 0.03 + 400000 * 0.015 + (profit - 1000000) * 0   
.01;
    }

    printf("应发奖金为:%.2lf\n", bonus);

    return 0;
}


2. 使用 switch 语句(相对复杂,不推荐)
由于利润区间是连续的,直接使用 switch 语句不太方便。如果一定要用 switch,可以将利润分成多个区间,然后在每个 case 中再进行判断,但代码会比较冗余。

4.9 

#include <stdio.h>
#include <math.h>

int main() {
    double x, y, distance, radius = 1.0;
    int height;

    printf("请输入点的横坐标和纵坐标(用空格隔开):");
    scanf("%lf %lf", &x, &y);

    // 定义四个圆心的坐标
    double centers[4][2] = {
   
   {2, 2}, {-2, 2}, {-2, -2}, {2, -2}};

    height = 0; // 初始化高度为0
    for (int i = 0; i < 4; i++) {
        distance = sqrt(pow(x - centers[i][0], 2) + pow(y - centers[i][1], 2));
        if (distance <= radius) {
            height = 10;
            break; // 一旦找到一个圆内,就退出循环
        }
    }

    printf("该点的高度为:%dm\n", height);

    return 0;
}

4.10 

#include <stdio.h>
#include <math.h>

int main() {
    double a, b, c, discriminant, root1, root2;

    // 从用户输入一元二次方程的系数
    printf("请输入一元二次方程的系数a, b, c: ");
    scanf("%lf %lf %lf", &a, &b, &c);

    // 判断是否为二次方程
    if (a == 0) {
        // 如果 a 为 0,则不是二次方程,而是线性方程
        if (b == 0) {
            // 如果 a 和 b 都为 0,则方程有无穷多个解或无解,取决于 c 的值
            if (c == 0) {
                printf("方程有无穷多个解\n");
            } else {
                printf("方程无解\n");
            }
        } else {
            // 如果 a 为 0,b 不为 0,则方程为线性方程,只有一个解
            printf("方程的根为: x = %.2lf\n", -c / b);
        }
    } else {
        // 如果 a 不为 0,则为二次方程
        // 计算判别式
        discriminant = b * b - 4 * a * c;
        // 根据判别式的值判断根的情况
        if (discriminant > 0) {
            // 判别式大于 0,有两个不相等的实根
            root1 = (-b + sqrt(discriminant)) / (2 * a);
            root2 = (-b - sqrt(discriminant)) / (2 * a);
            printf("方程有两个不相等的实根: x1 = %.2lf, x2 = %.2lf\n", root1, root2);
        } else if (discriminant == 0) {
            // 判别式等于 0,有两个相等的实根
            root1 = root2 = -b / (2 * a);
            printf("方程有两个相等的实根: x1 = x2 = %.2lf\n", root1);
        } else {
            // 判别式小于 0,有两个共轭复根
            printf("方程有两个共轭复根\n");
        }
    }

    return 0;
}

第五章: 

5.1 

#include <stdio.h>
#include <math.h>

int main() {
    int i, j;
    int flag;

    printf("100-200之间的素数有:\n");

    for (i = 101; i <= 200; i++) {
        flag = 1;  // 假设 i 是素数
        for (j = 2; j <= sqrt(i); j++) {
            if (i % j == 0) {
                flag = 0;  // 如果 i 能被 j 整除,则 i 不是素数
                break;
            }
        }
        if (flag == 1) {
            printf("%d ", i);
        }
    }

    printf("\n");
    return 0;
}

5.2 

#include <stdio.h>
#include <ctype.h>

int main() {
    char ch;
    int alpha = 0, space = 0, digit = 0, other = 0;

    printf("请输入一行字符:\n");

    while ((ch = getchar()) != '\n') {
        if (isalpha(ch)) {
            alpha++;
        } else if (isspace(ch)) {
            space++;
        } else if (isdigit(ch)) {
            digit++;
        } else {
            other++;
        }
    }

    printf("英文字母个数:%d\n", alpha);
    printf("空格个数:%d\n", space);
    printf("数字个数:%d\n", digit);
    printf("其他字符个数:%d\n", other);

    return 0;
}

5.3 

#include <stdio.h>

int main() {
    int i, j, k, n;

    printf("所有的水仙花数是:\n");

    for (n = 100; n < 1000; n++) {
        i = n / 100;  // 百位
        j = n / 10 % 10;  // 十位
        k = n % 10;  // 个位
        if (i * i * i + j * j * j + k * k * k == n) {
            printf("%d ", n);
        }
    }

    printf("\n");
    return 0;
}

 5.4

#include <stdio.h>

int main() {
    int day = 10;  // 天数
    int peach = 1;  // 第10天剩下的桃子数

    for (int i = day - 1; i > 0; i--) {
        peach = (peach + 1) * 2;  // 逆推计算前一天的桃子数
    }

    printf("第一天摘了%d个桃子\n", peach);

    return 0;
}

 5.5

#include <stdio.h>
#include <math.h>

int main() {
    double height = 100.0; // 初始高度
    int times = 10; // 落地次数
    double total_distance, rebound_height;

    // 计算前9次落地共经过的路程
    total_distance = height * (pow(2, times - 1) - 1);
    // 计算第10次下落的路程并加上
    total_distance += height / pow(2, times - 1);

    // 计算第10次反弹的高度
    rebound_height = height / pow(2, times);

    printf("第10次落地时共经过了%.2f米\n", total_distance);
    printf("第10次反弹高度为%.2f米\n", rebound_height);

    return 0;
}

5.6 

5.7 

#include <stdio.h>

int main() {
    char teamA[] = {'A', 'B', 'C'};
    char teamB[] = {'X', 'Y', 'Z'};

    printf("所有可能的比赛配对:\n");

    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 3; j++) {
            for (int k = 0; k < 3; k++) {
                if (teamA[i] != 'A' || teamB[j] != 'X') {  // A不和X比
                    if (teamA[i] != 'C' || (teamB[k] != 'X' && teamB[k] != 'Z')) {  // C不和X、Z比
                        printf("%c vs %c\n", teamA[i], teamB[j]);
                        printf("%c vs %c\n", teamA[2 - i - j], teamB[3 - j - k]);
                        printf("%c vs %c\n\n", teamA[2 - i], teamB[2 - k]);
                    }
                }
            }
        }
    }

    return 0;
}

第六章: 

6.1 

#include <stdio.h>

int main() {
    int scores[10], i, sum = 0;
    double average;

    printf("请输入10个学生的成绩:\n");
    for (i = 0; i < 10; i++) {
        scanf("%d", &scores[i]);
        sum += scores[i];
    }

    average = (double)sum / 10;
    printf("平均成绩为:%.2lf\n", average);

    return 0;
}

6.2 

#include <stdio.h>

int main() {
    int scores[10][5], i, j, sum, highest_course, highest_score = 0;
    double average;

    // 输入10个学生5门课的成绩
    printf("请输入10个学生5门课的成绩:\n");
    for (i = 0; i < 10; i++) {
        for (j = 0; j < 5; j++) {
            scanf("%d", &scores[i][j]);
        }
    }

    // 计算每门课的平均分,并找出最高分对应的课程
    for (j = 0; j < 5; j++) {
        sum = 0;
        for (i = 0; i < 10; i++) {
            sum += scores[i][j];
        }
        average = (double)sum / 10;
        if (average > highest_score) {
            highest_score = average;
            highest_course = j + 1; // 课程号从1开始
        }
    }

    printf("平均成绩最高的课程是第%d门课,平均成绩为:%.2lf\n", highest_course, highest_score);

    return 0;
}

6.3 

#include <stdio.h>

int main() {
    int scores[10], i, max_score = 0, max_index = 0;

    printf("请输入10个学生的成绩:\n");
    for (i = 0; i < 10; i++) {
        scanf("%d", &scores[i]);
    }

    // 遍历数组,找出最大值和对应的索引
    for (i = 0; i < 10; i++) {
        if (scores[i] > max_score) {
            max_score = scores[i];
            max_index = i;
        }
    }

    printf("最高分是:%d\n", max_score);
    printf("最高分学生的序号是:%d\n", max_index + 1); // 序号从1开始

    return 0;
}

 6.4

#include <stdio.h>

int main() {
    int scores[3][4], i, j, sum;
    double average;

    // 输入3个学生4门课的成绩
    printf("请输入3个学生4门课的成绩:\n");
    for (i = 0; i < 3; i++) {
        for (j = 0; j < 4; j++) {
            scanf("%d", &scores[i][j]);
        }
    }

    // 计算每门课的平均成绩
    for (j = 0; j < 4; j++) {
        sum = 0;
        for (i = 0; i < 3; i++) {
            sum += scores[i][j];
        }
        average = (double)sum / 3;
        printf("第%d门课的平均成绩为:%.2lf\n", j + 1, average);
    }

    return 0;
}

6.5 

#include <stdio.h>

#define STUDENTS 5
#define COURSES 4

void swap(int *a, int *b) {
    int temp = *a;
    *a = *b;
    *b = temp;
}

void sort_students(int scores[][COURSES], int n) {
    int i, j;
    for (i = 0; i < n - 1; i++) {
        for (j = i + 1; j < n; j++) {
            int sum1 = 0, sum2 = 0;
            for (int k = 0; k < COURSES; k++) {
                sum1 += scores[i][k];
                sum2 += scores[j][k];
            }
            if (sum1 < sum2) {
                // 交换两行数据
                for (int k = 0; k < COURSES; k++) {
                    swap(&scores[i][k], &scores[j][k]);
                }
            }
        }
    }
}

int main() {
    int scores[STUDENTS][COURSES];
    int i, j, sum;
    double average;

    // 输入5个学生4门课的成绩
    printf("请输入5个学生4门课的成绩:\n");
    for (i = 0; i < STUDENTS; i++) {
        for (j = 0; j < COURSES; j++) {
            scanf("%d", &scores[i][j]);
        }
    }

    // 计算每个学生的平均成绩并排序
    sort_students(scores, STUDENTS);

    // 输出排序后的成绩
    printf("排序后的成绩:\n");
    for (i = 0; i < STUDENTS; i++) {
        sum = 0;
        for (j = 0; j < COURSES; j++) {
            sum += scores[i][j];
            printf("%d ", scores[i][j]);
        }
        average = (double)sum / COURSES;
        printf("平均成绩:%.2lf\n", average);
    }

    return 0;
}

 6.6

#include <stdio.h>

void reverse(int arr[], int n) {
    int temp[n];
    for (int i = 0; i < n; i++) {
        temp[i] = arr[n - i - 1];
    }
    for (int i = 0; i < n; i++) {
        arr[i] = temp[i];
    }
}

int main() {
    int arr[] = {8, 6, 5, 4, 1};
    int n = sizeof(arr) / sizeof(arr[0]);

    printf("原始数组:");
    for (int i = 0; i < n; i++) {
        printf("%d ", arr[i]);
    }

    reverse(arr, n);

    printf("\n逆序后数组:");
    for (int i = 0; i < n; i++) {
        printf("%d ", arr[i]);
    }

    return 0;
}

6.7 

6.8 

#include <stdio.h>
#include <ctype.h>

int main() {
    char str[3][80];
    int i, j, upper = 0, lower = 0, digit = 0, space = 0, others = 0;

    printf("请输入三行文字,每行不超过80个字符:\n");
    for (i = 0; i < 3; i++) {
        fgets(str[i], 80, stdin); // 读取一行,包括换行符
    }

    for (i = 0; i < 3; i++) {
        for (j = 0; str[i][j] != '\0'; j++) {
            if (isalpha(str[i][j])) {
                if (isupper(str[i][j])) {
                    upper++;
                } else {
                    lower++;
                }
            } else if (isdigit(str[i][j])) {
                digit++;
            } else if (isspace(str[i][j])) {
                space++;
            } else {
                others++;
            }
        }
    }

    printf("大写字母:%d\n", upper);
    printf("小写字母:%d\n", lower);
    printf("数字:%d\n", digit);
    printf("空格:%d\n", space);
    printf("其他字符:%d\n", others);

    return 0;
}

 6.9

#include <stdio.h>
#include <ctype.h>

void decrypt(char *str) {
    int len = strlen(str);
    for (int i = 0; i < len; i++) {
        if (isalpha(str[i])) {
            if (isupper(str[i])) {
                str[i] = 'Z' - (str[i] - 'A');
            } else {
                str[i] = 'z' - (str[i] - 'a');
            }
        }
    }
}

int main() {
    char cipher[] = "Umtorhs";
    printf("密码:%s\n", cipher);

    decrypt(cipher);

    printf("原文:%s\n", cipher);

    return 0;
}

6.10 

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

int main() {
    char str1[50] = "Hello, ";
    char str2[] = "world!";
    char result[100];

    strcpy(result, str1); // 将 str1 复制到 result
    strcat(result, str2); // 将 str2 连接到 result 的末尾

    printf("连接后的字符串:%s\n", result);

    return 0;
}
#include <stdio.h>

int main() {
    char str1[50] = "Hello, ";
    char str2[] = "world!";
    char result[100];
    int i, j;

    for (i = 0; str1[i] != '\0'; i++) {
        result[i] = str1[i];
    }
    for (j = 0; str2[j] != '\0'; j++) {
        result[i++] = str2[j];
    }
    result[i] = '\0'; // 添加字符串结束符

    printf("连接后的字符串:%s\n", result);

    return 0;
}

第七章: 

7.1 

#include <stdio.h>

// 求最大公约数的函数
int gcd(int a, int b) {
    // 辗转相除法求最大公约数
    while (b != 0) {
        int temp = a % b; // 计算余数
        a = b; // 将b的值赋给a
        b = temp; // 将余数赋给b
    }
    return a; // 最后剩下的a就是最大公约数
}

// 求最小公倍数的函数
int lcm(int a, int b) {
    // 最小公倍数 = a * b / 最大公约数
    return a * b / gcd(a, b);
}

int main() {
    int num1, num2;

    printf("请输入两个整数:");
    scanf("%d %d", &num1, &num2);

    // 调用gcd函数求最大公约数
    int greatestCommonDivisor = gcd(num1, num2);
    // 调用lcm函数求最小公倍数
    int leastCommonMultiple = lcm(num1, num2);

    printf("最大公约数是:%d\n", greatestCommonDivisor);
    printf("最小公倍数是:%d\n", leastCommonMultiple);

    return 0;
}

7.2 

#include <stdio.h>
#include <math.h>

int is_prime(int num) {
    if (num <= 1) {
        return 0; // 1 及以下不是素数
    }
    if (num <= 3) {
        return 1; // 2 和 3 是素数
    }
    if (num % 2 == 0 || num % 3 == 0) {
        return 0; // 能被 2 或 3 整除的不是素数
    }
    
    for (int i = 5; i * i <= num; i += 6) {
        if (num % i == 0 || num % (i + 2) == 0) {
            return 0;
        }
    }

    return 1; // 如果循环结束,说明是素数
}

int main() {
    int num;

    printf("请输入一个整数:");
    scanf("%d", &num);

    if (is_prime(num)) {
        printf("%d 是素数\n", num);
    } else {
        printf("%d 不是素数\n", num);
    }

    return 0;
}

7.3 

#include <stdio.h>

// 函数功能:将一个3x3的二维数组进行转置(行列互换)
void transpose(int arr[3][3]) {
    // 遍历矩阵的上三角部分(不包括对角线)
    for (int i = 0; i < 3; i++) {
        for (int j = i + 1; j < 3; j++) {
            // 交换元素arr[i][j]和arr[j][i]
            int temp = arr[i][j];
            arr[i][j] = arr[j][i];
            arr[j][i] = temp;
        }
    }
}

int main() {
    int arr[3][3] = {
   
   {1, 2, 3}, {4, 5, 6}, {7, 8, 9}};

    printf("原矩阵:\n");
    // 输出原矩阵
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 3; j++) {
            printf("%d ", arr[i][j]);
        }
        printf("\n");
    }

    // 调用transpose函数进行转置
    transpose(arr);

    printf("转置后矩阵:\n");
    // 输出转置后的矩阵
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 3; j++) {
            printf("%d ", arr[i][j]);
        }
        printf("\n");
    }

    return 0;
}

7.4 

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

void reverseString(char str[]) {
    int len = strlen(str);
    // 双指针法:i从头开始,j从尾开始,交换字符
    for (int i = 0, j = len - 1; i < j; i++, j--) {
        char temp = str[i];
        str[i] = str[j];
        str[j] = temp;
    }
}

int main() {
    char str[100];

    printf("请输入一个字符串:");
    scanf("%s", str);

    reverseString(str);

    printf("反转后的字符串:%s\n", str);

    return 0;
}

7.5 

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

void concatStrings(char str1[], char str2[]) {
    // 获取两个字符串的长度
    int len1 = strlen(str1);
    int len2 = strlen(str2);

    // 将str2的字符逐个复制到str1的末尾
    for (int i = 0; i < len2; i++) {
        str1[len1 + i] = str2[i];
    }

    // 在字符串末尾添加字符串结束符
    str1[len1 + len2] = '\0';
}

int main() {
    char str1[50] = "BEI";
    char str2[50] = "JING";

    concatStrings(str1, str2);

    printf("连接后的字符串:%s\n", str1);

    return 0;
}

7.6 

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

void copyVowels(char str[], char vowels[]) {
    int i, j = 0;
    int len = strlen(str);
    for (i = 0; i < len; i++) {
        // 判断是否是元音字母(小写和大写)
        if (str[i] == 'a' || str[i] == 'e' || str[i] == 'i' || str[i] == 'o' || str[i] == 'u' ||
            str[i] == 'A' || str[i] == 'E' || str[i] == 'I' || str[i] == 'O' || str[i] == 'U') {
            vowels[j++] = str[i];
        }
    }
    vowels[j] = '\0'; // 在末尾添加字符串结束符
}

int main() {
    char str[100], vowels[100];

    printf("请输入一个字符串:");
    scanf("%s", str);

    copyVowels(str, vowels);

    printf("元音字母:%s\n", vowels);

    return 0;
}

7.7 

#include <stdio.h>

void split_and_print(int number) {
    int thousands = number / 1000;
    int hundreds = (number % 1000) / 100;
    int tens = (number % 100) / 10;
    int ones = number % 10;

    printf("%d %d %d %d\n", thousands, hundreds, tens, ones);
}

int main() {
    int num;
    printf("请输入一个4位数字:");
    scanf("%d", &num);

    split_and_print(num);

    return 0;
}

7.8 

#include <stdio.h>
#include <ctype.h>

void count_chars(char str[]) {
    int alpha = 0, digit = 0, space = 0, other = 0;
    int i;

    for (i = 0; str[i] != '\0'; i++) {
        if (isalpha(str[i])) {
            alpha++;
        } else if (isdigit(str[i])) {
            digit++;
        } else if (isspace(str[i])) {
            space++;
        } else {
            other++;
        }
    }

    printf("字母个数:%d\n", alpha);
    printf("数字个数:%d\n", digit);
    printf("空格个数:%d\n", space);
    printf("其他字符个数:%d\n", other);
}

int main() {
    char str[100];

    printf("请输入一个字符串:");
    fgets(str, 100, stdin);

    count_chars(str);

    return 0;
}

 7.9

#include <stdio.h> // 包含标准输入输出库
#include <string.h> // 包含字符串处理函数库

void find_longest_word(char str[]) { // 定义一个函数,用于查找最长单词
    int i, len = strlen(str), max_len = 0, start = 0; // 声明变量:循环变量、字符串长度、最大长度、当前单词起始位置

    // 遍历整个字符串
    for (i = 0; i < len; i++) {
        // 如果遇到空格或字符串结束符,说明一个单词结束
        if (str[i] == ' ' || str[i] == '\0') {
            // 计算当前单词的长度
            int current_len = i - start;
            // 如果当前单词的长度大于最大长度,更新最大长度和起始位置
            if (current_len > max_len) {
                max_len = current_len;
                // 记录最长单词的起始位置
                start = i + 1;
            } else {
                // 如果不是最长单词,则将起始位置更新为下一个单词的开始
                start = i + 1;
            }
        }
    }

    // 输出最长单词
    for (i = start - max_len; i < start; i++) {
        printf("%c", str[i]); // 逐个输出最长单词的字符
    }
    printf("\n"); // 输出换行符
}

int main() { // 主函数
    char str[100]; // 定义一个字符数组存储输入的字符串

    printf("请输入一行字符:"); // 提示用户输入
    fgets(str, 100, stdin); // 从标准输入读取一行字符串

    find_longest_word(str); // 调用函数查找并输出最长单词

    return 0; // 程序正常退出
}

7.10 

#include <stdio.h>

void bubble_sort_chars(char arr[]) {
    int i, j;
    char temp;

    for (i = 0; i < 10; i++) {
        for (j = 0; j < 9 - i; j++) {
            if (arr[j] > arr[j+1]) {
                // 交换两个字符的位置
                temp = arr[j];
                arr[j] = arr[j+1];
                arr[j+1] = temp;
            }
        }
    }
}

int main() {
    char chars[10];

    printf("请输入10个字符:");
    scanf("%s", chars);

    bubble_sort_chars(chars);

    printf("排序后的字符:%s\n", chars);

    return 0;
}

7.11 

#include <stdio.h>

#define STUDENTS 10
#define COURSES 5

void input_scores(int scores[STUDENTS][COURSES]) {
    printf("请输入10个学生5门课的成绩:\n");
    for (int i = 0; i < STUDENTS; i++) {
        for (int j = 0; j < COURSES; j++) {
            scanf("%d", &scores[i][j]);
        }
    }
}

void calculate_student_average(int scores[STUDENTS][COURSES], double averages[STUDENTS]) {
    for (int i = 0; i < STUDENTS; i++) {
        int sum = 0;
        for (int j = 0; j < COURSES; j++) {
            sum += scores[i][j];
        }
        averages[i] = (double)sum / COURSES;
    }
}

void calculate_course_average(int scores[STUDENTS][COURSES], double averages[COURSES]) {
    for (int i = 0; i < COURSES; i++) {
        int sum = 0;
        for (int j = 0; j < STUDENTS; j++) {
            sum += scores[j][i];
        }
        averages[i] = (double)sum / STUDENTS;
    }
}

void find_highest_score(int scores[STUDENTS][COURSES]) {
    int max_score = scores[0][0];
    int max_student = 0, max_course = 0;
    for (int i = 0; i < STUDENTS; i++) {
        for (int j = 0; j < COURSES; j++) {
            if (scores[i][j] > max_score) {
                max_score = scores[i][j];
                max_student = i;
                max_course = j;
            }
        }
    }
    printf("最高分是%d分,由第%d个学生在第%d门课取得。\n", max_score, max_student + 1, max_course + 1);
}

int main() {
    int scores[STUDENTS][COURSES];
    double student_averages[STUDENTS], course_averages[COURSES];

    input_scores(scores);
    calculate_student_average(scores, student_averages);
    calculate_course_average(scores, course_averages);
    find_highest_score(scores);

    // 输出每个学生的平均分
    printf("每个学生的平均分:\n");
    for (int i = 0; i < STUDENTS; i++) {
        printf("学生%d:%.2lf\n", i + 1, student_averages[i]);
    }

    // 输出每门课的平均分
    printf("\n每门课的平均分:\n");
    for (int i = 0; i < COURSES; i++) {
        printf("课程%d:%.2lf\n", i + 1, course_averages[i]);
    }

    return 0;
}

 7.12

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

#define MAX_EMPLOYEES 10
#define NAME_LEN 20

typedef struct {
    char name[NAME_LEN];
    int number;
} Employee;

void input_employees(Employee employees[]) {
    for (int i = 0; i < MAX_EMPLOYEES; i++) {
        printf("请输入第%d个员工的姓名和职工号:", i + 1);
        scanf("%s %d", employees[i].name, &employees[i].number);
    }
}

void bubble_sort_by_number(Employee employees[]) {
    Employee temp;
    for (int i = 0; i < MAX_EMPLOYEES - 1; i++) {
        for (int j = 0; j < MAX_EMPLOYEES - i - 1; j++) {
            if (employees[j].number > employees[j + 1].number) {
                temp = employees[j];
                employees[j] = employees[j + 1];
                employees[j + 1] = temp;
            }
        }
    }
}

int binary_search(Employee employees[], int number, int left, int right) {
    if (left > right) {
        return -1; // 未找到
    }
    int mid = (left + right) / 2;
    if (employees[mid].number == number) {
        return mid;
    } else if (employees[mid].number < number) {
        return binary_search(employees, number, mid + 1, right);
    } else {
        return binary_search(employees, number, left, mid - 1);
    }
}

int main() {
    Employee employees[MAX_EMPLOYEES];

    input_employees(employees);

    bubble_sort_by_number(employees);

    printf("排序后的员工信息:\n");
    for (int i = 0; i < MAX_EMPLOYEES; i++) {
        printf("姓名:%s,职工号:%d\n", employees[i].name, employees[i].number);
    }

    int search_number;
    printf("请输入要查找的职工号:");
    scanf("%d", &search_number);

    int index = binary_search(employees, search_number, 0, MAX_EMPLOYEES - 1);
    if (index != -1) {
        printf("找到该员工,姓名为:%s\n", employees[index].name);
    } else {
        printf("未找到该员工\n");
    }

    return 0;
}

7.13 

#include <stdio.h>

int findMax(int num1, int num2, int num3, int num4) {
    if (num1 >= num2 && num1 >= num3 && num1 >= num4) {
        return num1;
    } else {
        return findMax(num2, num3, num4, num1);
    }
}

int main() {
    int a, b, c, d;

    printf("请输入四个整数:");
    scanf("%d %d %d %d", &a, &b, &c, &d);

    int max = findMax(a, b, c, d);

    printf("最大的数是:%d\n", max);

    return 0;
}

7.14 

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

void int_to_str(int num, char *str) {
    if (num == 0) {
        *str = '\0'; // 递归结束条件:当数字为0时,字符串的末尾置为'\0'
        return;
    }
    int_to_str(num / 10, str + 1); // 递归调用,处理除个位数以外的数字
    *str = num % 10 + '0'; // 将个位数转换为字符,并存入字符串
}

int main() {
    int num;
    char str[100]; // 存放转换后的字符串

    printf("请输入一个整数:");
    scanf("%d", &num);

    int_to_str(num, str);

    printf("转换后的字符串为:%s\n", str);

    return 0;
}

7.15 

#include <stdio.h>

int is_leap_year(int year) {
    return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
}

int days_in_month(int year, int month) {
    int days[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    if (month == 2) {
        return is_leap_year(year) ? 29 : 28;
    }
    return days[month - 1];
}

int day_of_year(int year, int month, int day) {
    int sum = 0;
    for (int m = 1; m < month; m++) {
        sum += days_in_month(year, m);
    }
    sum += day;
    return sum;
}

int main() {
    int year, month, day;

    printf("请输入年份、月份、日期(用空格隔开): ");
    scanf("%d %d %d", &year, &month, &day);

    if (year < 1 || month < 1 || month > 12 || day < 1 || day > days_in_month(year, month)) {
        printf("输入日期非法!\n");
        return 1;
    }

    int result = day_of_year(year, month, day);
    printf("%d年%d月%d日是该年的第%d天\n", year, month, day, result);

    return 0;
}

第八章: 

8.1 

#include <stdio.h>

void sortThreeNumbers(int a, int b, int c) {
    // 使用嵌套的if语句进行排序
    if (a > b) {
        int temp = a;
        a = b;
        b = temp;
    }
    if (a > c) {
        int temp = a;
        a = c;
        c = temp;
    }
    if (b > c) {
        int temp = b;
        b = c;
        c = temp;
    }

    printf("从小到大排序后的结果:%d %d %d\n", a, b, c);
}

int main() {
    int num1, num2, num3;

    printf("请输入三个整数:");
    scanf("%d %d %d", &num1, &num2, &num3);

    sortThreeNumbers(num1, num2, num3);

    return 0;
}

8.2 

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

void sortStrings(char str1[], char str2[], char str3[]) {
    // 使用字符串比较函数strcmp进行比较和交换
    if (strcmp(str1, str2) > 0) {
        char temp[50];
        strcpy(temp, str1);
        strcpy(str1, str2);
        strcpy(str2, temp);
    }
    if (strcmp(str1, str3) > 0) {
        char temp[50];
        strcpy(temp, str1);
        strcpy(str1, str3);
        strcpy(str3, temp);
    }
    if (strcmp(str2, str3) > 0) {
        char temp[50];
        strcpy(temp, str2);
        strcpy(str2, str3);
        strcpy(str3, temp);
    }

    printf("从小到大排序后的字符串:\n");
    printf("%s\n", str1);
    printf("%s\n", str2);
    printf("%s\n", str3);
}

int main() {
    char str1[50], str2[50], str3[50];

    printf("请输入三个字符串:\n");
    scanf("%s %s %s", str1, str2, str3);

    sortStrings(str1, str2, str3);

    return 0;
}

8.3 

#include <stdio.h>

void input_numbers(int arr[]) {
    printf("请输入10个整数:\n");
    for (int i = 0; i < 10; i++) {
        scanf("%d", &arr[i]);
    }
}

void process_numbers(int arr[]) {
    int min = arr[0], max = arr[0], min_index = 0, max_index = 0;

    // 找到最小值和最大值及其索引
    for (int i = 1; i < 10; i++) {
        if (arr[i] < min) {
            min = arr[i];
            min_index = i;
        }
        if (arr[i] > max) {
            max = arr[i];
            max_index = i;
        }
    }

    // 交换最小值和第一个数
    int temp = arr[0];
    arr[0] = min;
    arr[min_index] = temp;

    // 交换最大值和最后一个数
    temp = arr[9];
    arr[9] = max;
    arr[max_index] = temp;
}

void output_numbers(int arr[]) {
    printf("交换后的数组:\n");
    for (int i = 0; i < 10; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");
}

int main() {
    int numbers[10];

    input_numbers(numbers);
    process_numbers(numbers);
    output_numbers(numbers);

    return 0;
}

 8.4

#include <stdio.h>

void moveElements(int arr[], int n, int m) {
    // 检查m的合法性
    if (m < 0 || m >= n) {
        printf("m的值不合法!\n");
        return;
    }

    // 创建一个临时数组,用于存储后m个元素
    int temp[m];
    for (int i = 0; i < m; i++) {
        temp[i] = arr[n - m + i];
    }

    // 将前n-m个元素向后移动m个位置
    for (int i = n - m - 1; i >= 0; i--) {
        arr[i + m] = arr[i];
    }

    // 将临时数组中的元素复制到数组的前面
    for (int i = 0; i < m; i++) {
        arr[i] = temp[i];
    }
}

int main() {
    int arr[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    int n = sizeof(arr) / sizeof(arr[0]);
    int m = 3;

    printf("原始数组:");
    for (int i = 0; i < n; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");

    moveElements(arr, n, m);

    printf("移动后数组:");
    for (int i = 0; i < n; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");

    return 0;
}

8.5 

#include <stdio.h>
#include <stdlib.h>

// 定义一个节点结构体,用来表示环形链表中的一个节点
typedef struct Node {
    int num;  // 节点的编号
    struct Node *next; // 指向下一个节点的指针
} Node;

// 创建一个环形链表,表示n个学生围成的圈
Node* createCircle(int n) {
    // 创建头节点
    Node *head = (Node*)malloc(sizeof(Node));
    head->num = 1;
    head->next = head; // 头节点的下一个节点指向自己,形成环

    // 创建其余节点,并连接起来
    Node *p = head;
    for (int i = 2; i <= n; i++) {
        Node *newNode = (Node*)malloc(sizeof(Node));
        newNode->num = i;
        p->next = newNode;
        p = newNode;
    }
    p->next = head; // 将最后一个节点的next指针指向头节点,完成环的闭合

    return head;
}

// 求解约瑟夫环问题,返回最后剩下学生的编号
int lastRemaining(int n, int m) {
    if (n < 1 || m < 1) {
        return -1; // 参数非法
    }

    // 创建环形链表
    Node *head = createCircle(n);

    // p指向当前节点
    Node *p = head;

    // 循环删除节点,直到链表中只剩下一个节点
    while (p->next != p) {
        // 跳过m-1个节点
        for (int i = 1; i < m; i++) {
            p = p->next;
        }

        // 删除第m个节点
        Node *temp = p->next;  // 保存要删除节点的下一个节点
        free(p->next);        // 释放要删除的节点
        p->next = temp;        // 将p的next指针指向下一个节点
    }

    return p->num; // 返回最后剩下节点的编号
}

int main() {
    int n, m;
    printf("请输入学生总数n和报数m:");
    scanf("%d %d", &n, &m);
    int result = lastRemaining(n, m);
    printf("最后剩下的是第%d号学生\n", result);
    return 0;
}

8.6 

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

// 定义一个函数,用于计算字符串的长度
int stringLength(char str[]) {
    int length = 0;
    while (str[length] != '\0') {
        length++;
    }
    return length;
}

int main() {
    char str[100];

    printf("请输入一个字符串:");
    scanf("%s", str);

    int len = stringLength(str);
    printf("该字符串的长度为:%d\n", len);

    return 0;
}

8.7 

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

void replaceSubstring(char *str1, char *str2, int start, int end) {
    // 检查索引是否越界
    if (start < 0 || end >= strlen(str2) || start > end) {
        printf("索引越界!\n");
        return;
    }

    // 计算需要替换的部分的长度
    int len = end - start + 1;

    // 计算str1中需要替换部分的起始位置
    int pos = 11; // 从第12个字符开始替换

    // 将str2中指定部分复制到str1中指定位置
    strncpy(str1 + pos, str2 + start, len);

    // 确保str1在替换后以'\0'结尾
    str1[pos + len] = '\0';
}

int main() {
    char str1[] = "My name is Li jilin.";
    char str2[] = "Mr Zhang Haoling is very happy.";

    replaceSubstring(str1, str2, 5, 17);

    printf("新的字符串 a: %s\n", str1);

    return 0;
}

8.8 

#include <stdio.h>
#include <ctype.h>

int main() {
    char str[100];
    int upper = 0, lower = 0, space = 0, digit = 0, others = 0;

    printf("请输入一行文字:");
    fgets(str, sizeof(str), stdin);

    // 去除末尾的换行符
    str[strcspn(str, "\n")] = '\0';

    for (int i = 0; str[i] != '\0'; i++) {
        if (isupper(str[i])) {
            upper++;
        } else if (islower(str[i])) {
            lower++;
        } else if (isspace(str[i])) {
            space++;
        } else if (isdigit(str[i])) {
            digit++;
        } else {
            others++;
        }
    }

    printf("大写字母有 %d 个\n", upper);
    printf("小写字母有 %d 个\n", lower);
    printf("空格有 %d 个\n", space);
    printf("数字有 %d 个\n", digit);
    printf("其他字符有 %d 个\n", others);

    return 0;
}

8.9 

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

#define MAX_STRINGS 10
#define MAX_LENGTH 20 // 假设每个字符串最大长度为20

void sortStrings(char strings[][MAX_LENGTH], int n) {
    for (int i = 0; i < n - 1; i++) {
        for (int j = i + 1; j < n; j++) {
            if (strcmp(strings[i], strings[j]) > 0) {
                // 交换两个字符串
                char temp[MAX_LENGTH];
                strcpy(temp, strings[i]);
                strcpy(strings[i], strings[j]);
                strcpy(strings[j], temp);
            }
        }
    }
}

int main() {
    char strings[MAX_STRINGS][MAX_LENGTH];

    printf("请输入10个字符串(每个字符串最大长度为 %d):\n", MAX_LENGTH);
    for (int i = 0; i < MAX_STRINGS; i++) {
        scanf("%s", strings[i]);
    }

    sortStrings(strings, MAX_STRINGS);

    printf("排序后的字符串:\n");
    for (int i = 0; i < MAX_STRINGS; i++) {
        printf("%s\n", strings[i]);
    }

    return 0;
}

8.10 

#include <stdio.h>

void reverseArray(int arr[], int n) {
    int temp;
    for (int i = 0; i < n / 2; i++) {
        // 交换数组头尾元素
        temp = arr[i];
        arr[i] = arr[n - i - 1];
        arr[n - i - 1] = temp;
    }
}

int main() {
    int n;
    printf("请输入数组元素个数:");
    scanf("%d", &n);

    int arr[n];
    printf("请输入%d个整数:\n", n);
    for (int i = 0; i < n; i++) {
        scanf("%d", &arr[i]);
    }

    reverseArray(arr, n);

    printf("逆序排列后的数组:\n");
    for (int i = 0; i < n; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");

    return 0;
}

8.11 

#include <stdio.h>

void inv(int *a, int n) {
    int temp;
    for (int i = 0; i < n / 2; i++) {
        // 交换数组头尾元素
        temp = a[i];
        a[i] = a[n - i - 1];
        a[n - i - 1] = temp;
    }
}

int main() {
    int arr[] = {1, 2, 3, 4, 5};
    int n = sizeof(arr) / sizeof(arr[0]);

    printf("原始数组:");
    for (int i = 0; i < n; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");

    inv(arr, n);

    printf("逆序后数组:");
    for (int i = 0; i < n; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");

    return 0;
}

8.12 

#include <stdio.h>
#include <ctype.h>

int main() {
    char str[100];
    int a[100], count = 0, num = 0;

    printf("请输入一个字符串:");
    fgets(str, sizeof(str), stdin);

    // 遍历字符串
    for (int i = 0; str[i] != '\0'; i++) {
        if (isdigit(str[i])) {
            // 如果是数字,则将该数字添加到当前数字
            num = num * 10 + (str[i] - '0');
        } else {
            // 如果不是数字,则将当前数字存入数组,并重置num
            if (num != 0) {
                a[count++] = num;
                num = 0;
            }
        }
    }

    // 处理最后一个数字
    if (num != 0) {
        a[count++] = num;
    }

    // 输出结果
    printf("提取出的整数有:\n");
    for (int i = 0; i < count; i++) {
        printf("%d ", a[i]);
    }
    printf("\n");

    return 0;
}

8.13 

#include <stdio.h>

void transpose(int arr[3][3]) {
    int temp;
    for (int i = 0; i < 3; i++) {
        for (int j = i + 1; j < 3; j++) {
            // 交换 arr[i][j] 和 arr[j][i]
            temp = arr[i][j];
            arr[i][j] = arr[j][i];
            arr[j][i] = temp;
        }
    }
}

int main() {
    int arr[3][3] = {
   
   {1, 2, 3}, {4, 5, 6}, {7, 8, 9}};

    printf("原始数组:\n");
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 3; j++) {
            printf("%d ", arr[i][j]);
        }
        printf("\n");
    }

    transpose(arr);

    printf("转置后的数组:\n");
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 3; j++) {
            printf("%d ", arr[i][j]);
        }
        printf("\n");
    }

    return 0;
}

第九章: 

9.1 

#include <stdio.h>

struct Date {
    int year;
    int month;
    int day;
};

int isLeapYear(int year) {
    return (year % 4 == 0 && year % 100 != 0) || year % 400 == 0;
}

int dayOfYear(struct Date date) {
    int daysInMonth[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    if (isLeapYear(date.year)) {
        daysInMonth[1] = 29;
    }

    int dayCount = 0;
    for (int i = 0; i < date.month - 1; i++) {
        dayCount += daysInMonth[i];
    }
    dayCount += date.day;
    return dayCount;
}

int main() {
    struct Date date;
    printf("请输入年份、月份、日期(用空格隔开): ");
    scanf("%d %d %d", &date.year, &date.month, &date.day);

    int result = dayOfYear(date);
    printf("%d年%d月%d日是这一年的第%d天\n", date.year, date.month, date.day, result);

    return 0;
}

9.2 

#include <stdio.h>

// 定义一个结构体表示日期
struct Date {
    int year;
    int month;
    int day;
};

// 判断是否是闰年
int isLeapYear(int year) {
    return (year % 4 == 0 && year % 100 != 0) || year % 400 == 0;
}

// 计算指定日期在一年中的第几天
int days(struct Date date) {
    int daysInMonth[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    if (isLeapYear(date.year)) {
        daysInMonth[1] = 29; // 闰年二月有29天
    }

    int sum = 0;
    for (int i = 0; i < date.month - 1; i++) {
        sum += daysInMonth[i]; // 累加前几个月的天数
    }
    sum += date.day; // 加上当月的天数
    return sum;
}

int main() {
    struct Date date;
    printf("请输入年份、月份、日期(用空格隔开): ");
    scanf("%d %d %d", &date.year, &date.month, &date.day);

    int result = days(date);
    printf("%d年%d月%d日是这一年的第%d天\n", date.year, date.month, date.day, result);

    return 0;
}

9.3 

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

#define MAX_STUDENTS 5
#define MAX_COURSES 3

struct Student {
    int num;
    char name[20];
    int score[MAX_COURSES];
};

void print(struct Student students[], int n) {
    printf("学号\t姓名\t\t成绩\n");
    for (int i = 0; i < n; i++) {
        printf("%d\t%s\t", students[i].num, students[i].name);
        for (int j = 0; j < MAX_COURSES; j++) {
            printf("%d ", students[i].score[j]);
        }
        printf("\n");
    }
}

int main() {
    struct Student students[MAX_STUDENTS];

    // 输入学生信息
    for (int i = 0; i < MAX_STUDENTS; i++) {
        printf("请输入第%d个学生的学号、姓名和三门课成绩:\n", i + 1);
        scanf("%d %s", &students[i].num, students[i].name);
        for (int j = 0; j < MAX_COURSES; j++) {
            scanf("%d", &students[i].score[j]);
        }
    }

    // 调用print函数输出学生信息
    print(students, MAX_STUDENTS);

    return 0;
}

9.4

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

#define MAX_STUDENTS 5
#define MAX_COURSES 3

struct Student {
    int num;
    char name[20];
    int score[MAX_COURSES];
};

// 输入学生信息
void input(struct Student students[]) {
    for (int i = 0; i < MAX_STUDENTS; i++) {
        printf("请输入第%d个学生的学号、姓名和三门课成绩:\n", i + 1);
        scanf("%d %s", &students[i].num, students[i].name);
        for (int j = 0; j < MAX_COURSES; j++) {
            scanf("%d", &students[i].score[j]);
        }
    }
}

// 打印学生信息
void print(struct Student students[], int n) {
    printf("学号\t姓名\t\t成绩\n");
    for (int i = 0; i < n; i++) {
        printf("%d\t%s\t", students[i].num, students[i].name);
        for (int j = 0; j < MAX_COURSES; j++) {
            printf("%d ", students[i].score[j]);
        }
        printf("\n");
    }
}

int main() {
    struct Student students[MAX_STUDENTS];

    // 调用input函数输入学生信息
    input(students);

    // 调用print函数输出学生信息
    print(students, MAX_STUDENTS);

    return 0;
}

 9.5

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

#define MAX_STUDENTS 10
#define MAX_COURSES 3

struct Student {
    int num;
    char name[20];
    int score[MAX_COURSES];
    double average; // 新增字段,存储平均分
};

// 计算平均分
double calculateAverage(int scores[], int numCourses) {
    int sum = 0;
    for (int i = 0; i < numCourses; i++) {
        sum += scores[i];
    }
    return (double)sum / numCourses;
}

// 按照平均分降序排序
void sortStudentsByAverage(struct Student students[]) {
    // 冒泡排序
    for (int i = 0; i < MAX_STUDENTS - 1; i++) {
        for (int j = 0; j < MAX_STUDENTS - i - 1; j++) {
            if (students[j].average < students[j + 1].average) {
                struct Student temp = students[j];
                students[j] = students[j + 1];
                students[j + 1] = temp;
            }
        }
    }
}

int main() {
    struct Student students[MAX_STUDENTS];

    // 输入学生信息
    for (int i = 0; i < MAX_STUDENTS; i++) {
        printf("请输入第%d个学生的学号、姓名和三门课成绩:\n", i + 1);
        scanf("%d %s", &students[i].num, students[i].name);
        for (int j = 0; j < MAX_COURSES; j++) {
            scanf("%d", &students[i].score[j]);
        }
        students[i].average = calculateAverage(students[i].score, MAX_COURSES);
    }

    // 按照平均分排序
    sortStudentsByAverage(students);

    // 输出学生信息
    printf("学号\t姓名\t\t成绩\t\t平均分\n");
    for (int i = 0; i < MAX_STUDENTS; i++) {
        printf("%d\t%s\t", students[i].num, students[i].name);
        for (int j = 0; j < MAX_COURSES; j++) {
            printf("%d ", students[i].score[j]);
        }
        printf("\t%.2lf\n", students[i].average);
    }

    return 0;
}

 9.6

#include <stdio.h>

#define NUM_PEOPLE 13

int main() {
    int people[NUM_PEOPLE];
    int count = NUM_PEOPLE; // 剩余人数
    int index = 0; // 当前报数的人的索引
    int countNum = 0; // 报数计数

    // 初始化数组
    for (int i = 0; i < NUM_PEOPLE; i++) {
        people[i] = i + 1;
    }

    while (count > 1) {
        countNum++;
        if (countNum == 3) {
            people[index] = 0; // 标记为出局
            count--;
            countNum = 0;
        }
        index = (index + 1) % NUM_PEOPLE; // 循环回到数组开头
        while (people[index] == 0) { // 找到下一个未出局的人
            index = (index + 1) % NUM_PEOPLE;
        }
    }

    printf("最后剩下的人的序号是:%d\n", people[index]);

    return 0;
}

 9.7

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

// 定义学生结构体
struct Student {
    int num;
    char name[20];
    int score;
    struct Student *next; // 指向下一个学生的指针
};

int main() {
    struct Student *head = NULL, *p, *newStudent;

    // 创建3个学生节点
    for (int i = 0; i < 3; i++) {
        newStudent = (struct Student *)malloc(sizeof(struct Student));
        printf("请输入第%d个学生的学号、姓名、成绩:\n", i + 1);
        scanf("%d %s %d", &newStudent->num, newStudent->name, &newStudent->score);
        newStudent->next = NULL;

        // 将新节点插入到链表的末尾
        if (head == NULL) {
            head = newStudent;
        } else {
            p = head;
            while (p->next != NULL) {
                p = p->next;
            }
            p->next = newStudent;
        }
    }

    // 遍历链表,输出学生信息
    printf("\n学生信息如下:\n");
    p = head;
    while (p != NULL) {
        printf("学号:%d\t姓名:%s\t成绩:%d\n", p->num, p->name, p->score);
        p = p->next;
    }

    return 0;
}

第十章: 

10.1 

C语言文件操作的特点
C语言的文件操作提供了灵活而强大的功能,主要特点如下:

缓冲I/O: C语言采用缓冲I/O方式,即数据在内存中有一个缓冲区,当缓冲区满或遇到特定条件时,才会进行实际的I/O操作。这种方式提高了I/O效率,但需要程序员注意缓冲区的管理。
文件指针: C语言使用文件指针来标识文件,通过对文件指针的操作实现对文件的读写。
多种文件类型: C语言支持文本文件和二进制文件的读写。
丰富的文件操作函数: C语言提供了多种文件操作函数,如 fopen、fclose、fread、fwrite 等,可以实现文件的打开、关闭、读写等操作。
标准输入输出: C语言将键盘和显示器抽象为标准输入和标准输出,可以通过 stdin、stdout 和 stderr 来进行操作,方便程序的输入输出。
缓冲文件系统和文件缓冲区
缓冲文件系统 是C语言中的一种文件访问方式,它在内存中为每个打开的文件分配一个缓冲区。这个缓冲区是系统自动分配和管理的,程序员通常不需要直接操作它。

文件缓冲区 的作用如下:

提高I/O效率: 减少了系统调用次数,提高了I/O效率。
简化编程: 程序员只需要关注数据的读写,而不需要关心底层的I/O细节。
提供缓冲功能: 可以进行批量读写,提高I/O效率。
缓冲文件系统的基本工作原理:

打开文件: 当程序打开一个文件时,系统会为该文件分配一个缓冲区。
读写操作: 当程序进行读写操作时,数据首先被读入或写入缓冲区,而不是直接写入磁盘。
缓冲区刷新: 当缓冲区满或遇到特定条件(如遇到 \n 或程序调用 fflush 函数)时,缓冲区中的数据就会被刷新到磁盘上。
关闭文件: 当程序关闭文件时,如果缓冲区中有未写入的数据,也会被强制写入磁盘。
缓冲文件系统的优点:

提高I/O效率: 减少了系统调用次数,提高了I/O效率。
简化编程: 程序员只需要关注数据的读写,而不需要关心底层的I/O细节。
提供缓冲功能: 可以进行批量读写,提高I/O效率。
缓冲文件系统的缺点:

数据丢失风险: 如果程序异常终止,缓冲区中的数据可能丢失。
缓冲区大小限制: 缓冲区的大小是有限的,如果数据量过大,可能会导致性能下降。
总结

缓冲文件系统是C语言文件操作的重要特点,它为程序员提供了一种高效、方便的文件操作方式。理解缓冲文件系统的原理和工作机制,对于编写高效、可靠的C语言程序非常重要。

10.2 

什么是文件型指针?
在C语言中,文件型指针(FILE指针)是一个指向文件结构的指针。这个结构体包含了文件相关的信息,比如文件名、文件打开方式、当前读写位置等。通过文件指针,程序就可以对文件进行各种操作,如打开、关闭、读写等。

你可以将文件指针想象成一个指向文件的“箭头”,通过这个箭头,你就可以对文件进行定位和操作。

声明文件指针:

FILE *fp;


通过文件指针访问文件的好处
抽象层: 文件指针提供了一个抽象层,将底层的文件操作细节隐藏起来,使得程序员可以更方便地进行文件操作。
统一接口: 对于不同的文件类型(文本文件、二进制文件),使用相同的方式进行操作,简化了编程。
灵活操作: 通过文件指针,可以对文件进行各种操作,包括打开、关闭、读写、定位等。
高效: 缓冲I/O机制使得文件操作更加高效。
标准化: 文件指针是C语言标准的一部分,提供了统一的文件操作接口。
文件指针的典型操作
打开文件: fopen() 函数用于打开一个文件,并返回一个指向该文件的 FILE 指针。
关闭文件: fclose() 函数用于关闭一个文件,释放系统资源。
读写文件: fread() 和 fwrite() 函数用于从文件读取数据和向文件写入数据。
定位文件指针: fseek() 函数用于将文件指针定位到指定的位置。
获取文件信息: ftell() 函数用于获取文件指针的当前位置,feof() 函数用于判断文件是否结束。


示例

#include <stdio.h>

int main() {
    FILE *fp;
    char str[20];

    // 打开一个文件,用于写入
    fp = fopen("test.txt", "w");
    fputs("Hello, world!", fp);
    fclose(fp);

    // 打开一个文件,用于读取
    fp = fopen("test.txt", "r");
    fgets(str, 20, fp);
    printf("%s", str);
    fclose(fp);

    return 0;
}


总结

文件指针是C语言中进行文件操作的重要工具,它提供了一种方便、灵活、高效的方式来管理文件。通过理解文件指针的概念和使用方法,你可以更好地进行C语言程序的开发。

10.3 

文件的打开与关闭:文件操作的基础
文件的打开
含义: 打开文件就是在程序运行时建立一个与指定文件的连接,为后续的读写操作做准备。这个连接通常被称为文件流。
目的:
获取文件信息: 确定文件是否存在、大小、类型等。
获取文件权限: 确定程序对文件的操作权限(读、写、追加等)。
分配系统资源: 为文件操作分配必要的系统资源,如缓冲区。
文件的关闭
含义: 关闭文件就是切断程序与文件的连接,释放系统资源。
目的:
释放系统资源: 关闭文件后,操作系统会回收分配给该文件的缓冲区等资源。
保证数据完整性: 关闭文件时,会将缓冲区中的数据写入磁盘,确保数据不会丢失。
避免资源泄漏: 如果不关闭文件,可能会导致系统资源耗尽,甚至程序崩溃。
为什么打开和关闭文件?
文件操作的必要步骤: 打开文件是进行任何文件操作的前提,关闭文件是完成文件操作后的收尾工作。
保证数据安全: 打开文件后,对文件进行的修改会先写入内存缓冲区,只有在关闭文件时才会写入磁盘。如果程序异常终止,没有来得及关闭文件,缓冲区中的数据可能会丢失。
提高系统效率: 每个打开的文件都会占用系统的资源,及时关闭不再使用的文件可以释放系统资源,提高系统效率。
避免文件损坏: 同时打开多个文件时,如果操作不当,可能会导致文件损坏。及时关闭文件可以减少这种风险。

总结
打开和关闭文件是文件操作中最基础的两个步骤。通过打开文件,程序可以与操作系统建立联系,获取文件信息并进行读写操作;而关闭文件则释放系统资源,保证数据安全。

形象比喻:

想象一个文件就像一本书,打开文件就相当于打开这本书,可以开始阅读或书写。关闭文件则相当于合上这本书,把书放回书架。如果不合上书,书页可能会被损坏,而且其他人也无法借阅这本书。

示例:

#include <stdio.h>

int main() {
    FILE *fp;
    fp = fopen("test.txt", "w"); // 打开文件,准备写入
    fputs("Hello, world!", fp);
    fclose(fp); // 关闭文件
    return 0;
}


注意:

在C语言中,使用 fopen() 函数打开文件,使用 fclose() 函数关闭文件。
打开文件时,需要指定打开模式(如读、写、追加等)。
关闭文件是一个非常重要的操作,不要忘记。
总结来说,打开和关闭文件是文件操作的基本操作,也是保证程序正确性和稳定性的重要环节。

10.4 

#include <stdio.h>
#include <ctype.h>

int main() {
    FILE *fp;
    char ch;

    // 打开文件,以写入模式打开,如果文件不存在则创建
    fp = fopen("test.txt", "w");
    if (fp == NULL) {
        printf("打开文件失败!\n");
        return 1;
    }

    // 逐个字符读取输入,直到遇到'!'
    printf("请输入字符串(以'!'结束):\n");
    while ((ch = getchar()) != '!') {
        // 将小写字母转换为大写字母
        if (islower(ch)) {
            ch = toupper(ch);
        }
        // 将转换后的字符写入文件
        fputc(ch, fp);
    }

    // 关闭文件
    fclose(fp);

    printf("转换完成,结果已保存到test.txt文件中。\n");
    return 0;
}

10.5

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

#define MAX_LEN 100

// 快速排序函数
void quickSort(char str[], int left, int right) {
    // ... 快速排序实现,此处省略 ...
}

int main() {
    FILE *fpA, *fpB, *fpC;
    char strA[MAX_LEN], strB[MAX_LEN], strC[MAX_LEN * 2];

    // 打开文件
    fpA = fopen("A.txt", "r");
    fpB = fopen("B.txt", "r");
    fpC = fopen("C.txt", "w");

    // 检查文件是否打开成功
    if (fpA == NULL || fpB == NULL || fpC == NULL) {
        printf("打开文件失败!\n");
        return 1;
    }

    // 读取文件内容
    fgets(strA, MAX_LEN, fpA);
    fgets(strB, MAX_LEN, fpB);

    // 合并字符串
    strcpy(strC, strA);
    strcat(strC, strB);

    // 对合并后的字符串进行排序
    quickSort(strC, 0, strlen(strC) - 1);

    // 将排序后的字符串写入文件
    fputs(strC, fpC);

    // 关闭文件
    fclose(fpA);
    fclose(fpB);
    fclose(fpC);

    return 0;
}

10.6 

#include <stdio.h>

struct Student {
    int num;
    char name[20];
    int score[3];
    double average;
};

int main() {
    FILE *fp;
    struct Student stu[5];
    int i, j;
    double sum;

    // 打开文件,以写入方式打开,如果文件不存在则创建
    fp = fopen("stud.txt", "w");
    if (fp == NULL) {
        printf("打开文件失败!\n");
        return 1;
    }

    // 输入学生信息
    for (i = 0; i < 5; i++) {
        printf("请输入第%d个学生的学号、姓名和3门成绩:\n", i + 1);
        scanf("%d %s %d %d %d", &stu[i].num, stu[i].name, &stu[i].score[0], &stu[i].score[1], &stu[i].score[2]);

        // 计算平均成绩
        sum = stu[i].score[0] + stu[i].score[1] + stu[i].score[2];
        stu[i].average = sum / 3.0;

        // 将学生信息写入文件
        fprintf(fp, "%d\t%s\t%d\t%d\t%d\t%.2lf\n", stu[i].num, stu[i].name, stu[i].score[0], stu[i].score[1], stu[i].score[2], stu[i].average);
    }

    // 关闭文件
    fclose(fp);

    printf("学生信息已成功写入文件!\n");
    return 0;
}

10.7 

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

#define MAX_STUDENTS 50

struct Student {
    int num;
    char name[20];
    int score[3];
    double average;
};

// 交换两个学生的信息
void swap(struct Student *a, struct Student *b) {
    struct Student temp = *a;
    *a = *b;
    *b = temp;
}

// 冒泡排序(按平均分降序)
void bubbleSort(struct Student arr[], int n) {
    for (int i = 0; i < n -

10.8 

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

#define MAX_STUDENTS 100

struct Student {
    int num;
    char name[20];
    int score[3];
    double average;
};

// ... (假设 bubbleSort 函数已定义)

int main() {
    FILE *fp_read, *fp_write;
    struct Student stu[MAX_STUDENTS];
    int n = 0;
    struct Student newStu;

    // 打开已排序的文件
    fp_read = fopen("stu_sort.txt", "r");
    if (fp_read == NULL) {
        printf("打开文件失败!\n");
        return 1;
    }

    // 读取学生信息
    while (fscanf(fp_read, "%d %s %d %d %d %lf", &stu[n].num, stu[n].name, &stu[n].score[0], &stu[n].score[1], &stu[n].score[2], &stu[n].average) != EOF) {
        n++;
    }
    fclose(fp_read);

    // 输入新学生信息
    printf("请输入新学生的学号、姓名和3门成绩:\n");
    scanf("%d %s %d %d %d", &newStu.num, newStu.name, &newStu.score[0], &newStu.score[1], &newStu.score[2]);
    newStu.average = (newStu.score[0] + newStu.score[1] + newStu.score[2]) / 3.0;

    // 插入新学生
    int i;
    for (i = n - 1; i >= 0 && stu[i].average < newStu.average; i--) {
        stu[i + 1] = stu[i];
    }
    stu[i + 1] = newStu;
    n++;

    // 打开新文件
    fp_write = fopen("new_stu_sort.txt", "w");

    // 写入更新后的学生信息
    for (i = 0; i < n; i++) {
        fprintf(fp_write, "%d\t%s\t%d\t%d\t%d\t%.2lf\n", stu[i].num, stu[i].name, stu[i].score[0], stu[i].score[1], stu[i].score[2], stu[i].average);
    }

    // 关闭文件
    fclose(fp_write);

    printf("学生信息已插入并排序,结果已保存到 new_stu_sort.txt 文件中。\n");
    return 0;
}

10.9 

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

#define MAX_STUDENTS 100

// ... (Student结构体和bubbleSort函数定义同上)

int main() {
    FILE *fp;
    struct Student stu[MAX_STUDENTS];
    int n = 0;
    struct Student newStu;

    // 打开文件,以读写方式打开
    fp = fopen("stu_sort.txt", "r+");
    if (fp == NULL) {
        printf("打开文件失败!\n");
        return 1;
    }

    // 读取学生信息
    while (fscanf(fp, "%d %s %d %d %d %lf", &stu[n].num, stu[n].name, &stu[n].score[0], &stu[n].score[1], &stu[n].score[2], &stu[n].average) != EOF) {
        n++;
    }

    // 输入新学生信息并插入排序
    // ... (同上)

    // 将文件指针移回文件开头
    fseek(fp, 0, SEEK_SET);

    // 将更新后的学生信息写入文件
    for (int i = 0; i < n; i++) {
        fprintf(fp, "%d\t%s\t%d\t%d\t%d\t%.2lf\n", stu[i].num, stu[i].name, stu[i].score[0], stu[i].score[1], stu[i].score[2], stu[i].average);
    }

    // 关闭文件
    fclose(fp);

    printf("学生信息已插入并排序,结果已保存到 stu_sort.txt 文件中。\n");
    return 0;
}

10.10 

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

#define MAX_NAME 20
#define MAX_ADDRESS 50

struct Employee {
    char name[MAX_NAME];
    int id;
    char gender[6];
    int age;
    char address[MAX_ADDRESS];
    double salary;
    char health[5];
    char education[20];
};

int main() {
    FILE *fp_in, *fp_out;
    struct Employee emp;

    // 打开源文件
    fp_in = fopen("employee.txt", "r");
    if (fp_in == NULL) {
        printf("打开文件失败!\n");
        return 1;
    }

    // 创建新文件
    fp_out = fopen("employee_salary.txt", "w");
    if (fp_out == NULL) {
        printf("创建文件失败!\n");
        fclose(fp_in);
        return 1;
    }

    // 读取并写入数据
    while (fscanf(fp_in, "%s %d %s %d %s %lf %s %s", emp.name, &emp.id, emp.gender, &emp.age, emp.address, &emp.salary, emp.health, emp.education) != EOF) {
        fprintf(fp_out, "%s\t%.2lf\n", emp.name, emp.salary);
    }

    // 关闭文件
    fclose(fp_in);
    fclose(fp_out);

    printf("数据提取完成!\n");
    return 0;
}

10.11 

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

#define MAX_EMPLOYEES 100

struct Employee {
    char name[20];
    int id;
    double salary;
};

int main() {
    FILE *fp;
    struct Employee employees[MAX_EMPLOYEES];
    int n = 0, delId;

    // 打开文件
    fp = fopen("employee.txt", "r+");
    if (fp == NULL) {
        printf("打开文件失败!\n");
        return 1;
    }

    // 读取文件内容
    while (fscanf(fp, "%s %d %lf", employees[n].name, &employees[n].id, &employees[n].salary) != EOF) {
        n++;
    }

    // 输入要删除的员工编号
    printf("请输入要删除的员工编号:");
    scanf("%d", &delId);

    // 查找并删除
    int i;
    for (i = 0; i < n; i++) {
        if (employees[i].id == delId) {
            // 将后面的元素前移
            for (int j = i; j < n - 1; j++) {
                employees[j] = employees[j + 1];
            }
            n--;
            break;
        }
    }

    if (i == n) {
        printf("未找到该员工!\n");
    } else {
        // 将文件指针移回文件开头
        fseek(fp, 0, SEEK_SET);

        // 写入修改后的数据
        for (i = 0; i < n; i++) {
            fprintf(fp, "%s %d %.2lf\n", employees[i].name, employees[i].id, employees[i].salary);
        }
    }

    // 关闭文件
    fclose(fp);

    return 0;
}

10.12 

#include <stdio.h>
#include <ctype.h>

#define MAX_LINE 100

int main() {
    FILE *fp;
    char str[MAX_LINE];

    // 1. 将输入的字符存储到文件中
    fp = fopen("data.txt", "w");
    if (fp == NULL) {
        printf("打开文件失败!\n");
        return 1;
    }

    printf("请输入多行字符,以Ctrl+Z结束输入:\n");
    while (fgets(str, MAX_LINE, stdin) != NULL) {
        fputs(str, fp);
    }
    fclose(fp);

    // 2. 从文件中读取数据并转换大小写
    fp = fopen("data.txt", "r");
    if (fp == NULL) {
        printf("打开文件失败!\n");
        return 1;
    }

    printf("转换后的字符:\n");
    while (fgets(str, MAX_LINE, fp) != NULL) {
        for (int i = 0; str[i] != '\0'; i++) {
            putchar(toupper(str[i]));
        }
    }
    fclose(fp);

    return 0;
}

到此完结!

祝大家在C语言的实践中有所收获!