《C程序设计(第四版)》谭浩强 课后习题答案(每日更新)

第1章 程序设计和C语言

1.什么是程序?什么是程序设计?
‌(1)程序是一组计算机能识别和执行的指令‌。
程序是为了完成特定任务而设计的一系列指令集合,它告诉计算机如何执行特定的操作。
程序的目的在于完成一项功能、工作或任务,并且流程和结果具有可重复性。

(2)程序设计是指从确定任务到得到结果、写出文档的全过程。
这个过程通常包括以下几个阶段:

‌问题分析‌:对待解决的问题进行分析,定义用户需求。
‌算法设计‌:设计解决问题的算法。
‌编写代码‌:将设计转化为计算机可以理解的代码。
‌编译调试‌:对编写的代码进行编译和调试,确保程序能够正确运行。

程序设计是一个智力活动,涉及到对问题的分析、设计、编码、测试和调试等步骤。
专业的程序设计人员通常被称为程序员。

2.为什么需要计算机语言?高级语言的特点?
(1)计算机语言是人机沟通的桥梁,
使程序员能够用更易理解的方式编写代码。

(2)高级语言的特点包括更接近人类语言、抽象化程度高、易于学习和使用,
以及通常具有更强的可移植性和丰富的库支持,这些特性让开发过程更高效。

3.正确理解以下名词及其含义:
(1)源程序  目标程序  可执行程序
源程序:
程序员用高级编程语言(如C、Java、Python等)编写的代码,
通常以文本文件形式存在。

目标程序:经过编译后的中间代码,通常是机器语言的形式,
但未必可以直接执行。它通常是为了生成可执行文件而存在。

可执行程序:经过编译和链接后的最终程序,能够在计算机上直接运行,
通常以特定格式(如.exe文件)存在。

(2)程序编辑  程序编译  程序连接
程序编辑:
使用文本编辑器或IDE(集成开发环境)编写和修改源程序的过程。

程序编译:
将源程序翻译成目标程序的过程,通常由编译器完成。

连接:
将多个目标程序和库文件链接成一个可执行程序的过程,通常由链接器完成。

(3)程序  程序模块  程序文件
程序:
指完成特定功能的指令集合,可以是一个完整的应用,也可以是库或工具。

程序模块:
指将程序分成独立的部分,每个模块负责特定的功能,便于管理和重用。

程序文件:
存储源代码、目标代码或可执行代码的文件,通常以特定后缀(如.c、.o、.exe等)标识。

(4)函数  主函数  被调用函数  库函数
函数:
一段可以重复使用的代码块,执行特定的任务。

主函数:
程序的入口点,通常是执行程序时首先运行的函数(如C语言中的main)。

被调用函数:
在主函数或其他函数中被调用的函数,执行具体的操作。

库函数:
预先定义好的函数,存放在库中,程序员可以直接调用,如数学库中的sin、cos等。

(5)程序调试  程序测试
程序调试:
识别和修复程序中错误或缺陷的过程,通常使用调试工具来观察程序的执行过程。

程序测试:
系统地检查程序的功能和性能,确保其满足需求,包括单元测试、集成测试、系统测试等。

4.自学本书附录A,熟悉上机运行C程序的方法,上机运行本章3个例题
自行解决 ^_^

5.请参照本章例题,编写一个C程序,输出以下信息:
*************************
Very good!
*************************
#include <stdio.h>

int main() {
    // 输出星号
    for (int i = 0; i < 10; i++) {
        printf("*");
    }
    printf("\n");

    // 输出信息
    printf("Very good!\n");

    // 再次输出星号
    for (int i = 0; i < 10; i++) {
        printf("*");
    }
    printf("\n");

    return 0;
}

6.编写一个C程序,输入a,b,c三个值,输出其中最大者
#include <stdio.h>

int main() {
    float a, b, c;
    printf("请输入三个数字 a, b, c:\n");
    scanf("%f %f %f", &a, &b, &c);

    float max;
    
    // 找出最大值
    if (a >= b && a >= c) {
        max = a;
    } else if (b >= a && b >= c) {
        max = b;
    } else {
        max = c;
    }

    printf("最大值是: %.2f\n", max);
    return 0;
}
7.上机运行以下程序,注意注释的方法。分析运行结果,掌握注释的用法。
(1)
#include <stdio.h>
int main()
printí("How do you do!\n"):
return 0;
//这是行注释,注释范围从//起至换行符止
(2)把第4行改为
printf("How do you do!\n");
/*这是块注释*/
(3)把第4行改为以下两行
printf("How do you do!\n");
/*这是块注释,如在本行内写不完,可以在下一行继续写,
这部分内容均不产生目标代码*/
(4)把第4行改为
//printf("How do you do!\n");
(5)把第4行改为
printf("//How do you do!\n");
//在输出的字符串中加入//
(6)用块注释符把几行语句都作为注释
/* printf("How do you do!\n");
return 0;*/
看一遍即可 ^_^

第2章 算法--程序的灵魂

1.什么是算法?试从日常生活中找3个例子,描述它们的算法。
算法是解决问题的一系列步骤或规则。
它可以用来处理各种任务,从简单的日常活动到复杂的计算。

以下是三个日常生活中的例子及其算法描述:

### 1. 煮水
**算法步骤**:
1. 准备一个干净的水壶。
2. 向水壶中加入适量的水。
3. 将水壶放在火源上(如炉子)。
4. 打开火源,调整到适中火力。
5. 等待水开始煮沸(观察气泡)。
6. 水煮沸后,关闭火源。
7. 小心倒出热水。

### 2. 洗手
**算法步骤**:
1. 打开水龙头,调节水温。
2. 湿润双手,用水冲洗。
3. 取适量洗手液,涂抹在手上。
4. 双手搓揉,确保覆盖所有手部(包括手掌、手背、指缝和指甲)。
5. 持续搓揉至少20秒。
6. 用清水冲洗双手,确保洗净。
7. 关闭水龙头,使用干净毛巾或纸巾擦干双手。

### 3. 制作三明治
**算法步骤**:
1. 准备食材(面包、火腿、奶酪、生菜等)。
2. 拿出两片面包,放在切板上。
3. 在第一片面包上放一片火腿。
4. 在火腿上放一片奶酪。
5. 在奶酪上放一些生菜。
6. 将第二片面包盖在生菜上。
7. 可选择切成两半,便于食用。
8. 上盘,享用。

这些例子展示了算法在日常生活中的应用,帮助我们有效地完成任务。

2.什么叫结构化的算法?为什么要提倡结构化的算法?
结构化的算法是指一种以清晰、规范的方式设计和表达的算法,
它通过分层、模块化和使用特定的控制结构(如顺序、选择和循环)来组织算法的步骤。
这种方法强调了算法的逻辑结构,使得其易于理解、维护和修改。

### 结构化算法的特点:
1. **模块化**:将复杂问题分解为较小的模块或子任务,每个模块完成特定功能。
2. **清晰性**:每一步骤都有明确的目的和逻辑,避免模糊和冗长的描述。
3. **可读性**:易于他人理解,便于团队合作和代码共享。
4. **可维护性**:修改和更新变得简单,减少了错误的可能性。

### 提倡结构化算法的原因:
1. **提高可理解性**:结构化算法使得算法逻辑更清晰,降低了理解难度。
2. **便于调试和测试**:清晰的结构使得找出错误和进行单元测试变得更加容易。
3. **促进团队协作**:多个人合作时,结构化算法使得不同成员可以在各自负责的模块上进行开发。
4. **提高效率**:通过模块化,可以重用现有的模块,减少重复劳动。
5. **增强灵活性**:结构化设计便于未来的扩展和修改,适应变化的需求。

总的来说,结构化算法能够帮助开发者更有效地管理复杂性,提升软件开发的整体质量和效率。

3.试述3种基本结构的特点,请另外设计两种基本结构(要符合基本结构的特点)。
算法的基本结构通常包括顺序结构、选择结构和循环结构。它们是构建更复杂算法的基础。

### 三种基本结构的特点

1. **顺序结构**:
   - **特点**:步骤按顺序执行,从上到下逐行处理。
   - **示例**:做饭的步骤,按顺序执行每个步骤,例如:准备食材、加热、混合等。

2. **选择结构**:
   - **特点**:根据条件的真假决定执行哪一部分,通常包括“如果...那么...”的逻辑。
   - **示例**:考试及格与否的判定。如果分数大于等于60,则输出“及格”,
               否则输出“未及格”。

3. **循环结构**:
   - **特点**:重复执行一段代码,直到满足某个条件为止,通常包括“重复...直到...”的逻辑。
   - **示例**:计算1到100的和,使用循环不断加1直到达到100。

### 设计两种符合基本结构特点的结构

4. **分支结构**:
   - **特点**:类似于选择结构,但可以有多个分支,每个分支根据不同条件执行不同的操作。
   - **示例**:根据天气情况选择穿衣方式。如果天气是晴天,穿短袖;如果是阴天,穿外套;
               如果是下雨,带伞。

5. **嵌套结构**:
   - **特点**:在一个结构内部包含另一个结构,可以是选择或循环结构,使得逻辑更复杂。
   - **示例**:在考试中,如果学生的成绩大于90,则判断是否参加奖学金评选(选择结构),
               并在评选中,可能会重复多次评审(循环结构)。

这五种结构组合使用,可以构建出更复杂的算法,适应各种问题的解决需求。


4.用传统流程图表示求解以下问题的算法
(1)有两个瓶子A和B,分别盛放醋和酱油,要求将它们互换(即A瓶原来盛醋,现改
盛酱油,B瓶则相反)。

1. 互换瓶子A和B中的内容
开始
将瓶子A中的内容临时保存
将瓶子B中的内容倒入瓶子A
将临时保存的内容倒入瓶子B
结束


(2)依次将10个数输人,要求输出其中最大的数,

2. 输出10个数中的最大数
开始
初始化最大数为第一个输入数
循环输入10个数
如果当前数大于最大数,则更新最大数
输出最大数
结束


(3)有3个数a,6,c,要求按大小顺序把它们输出。

3. 按大小顺序输出3个数
开始
输入3个数a、b、c
比较a、b、c
按顺序输出
结束


(4)求1十2+3+…+100。

4. 求1+2+...+100
开始
初始化和为0
循环从1到100
将当前数加到和上
输出和
结束


(5)判断一个数n能否同时被3和5整除

5. 判断一个数n能否同时被3和5整除
开始
输入n
如果n mod 3 == 0且n mod 5 == 0
输出“能被3和5整除”
否则
输出“不能被3和5整除”
结束


(6)将100~200之间的素数输出。

6. 输出100~200之间的素数
开始
循环从100到200
初始化标志为真
对于每个数,循环从2到该数的平方根
如果能被整除,标志置为假
如果标志为真,输出该数
结束


(7)求两个数m和n的最大公约数。

7. 求两个数m和n的最大公约数
开始
输入m和n
当n不等于0
temp = n
n = m mod n
m = temp
输出m(最大公约数)
结束


(8)求方程式ax^2+bx十c=0的根。分别考虑
①有两个不等的实根;
②有两个相等的实根。

8. 求方程式ax + bx + c = 0的根
开始
输入a, b, c
计算判别式D = b^2 - 4ac
如果D > 0
计算两个不等的实根
输出两个根
否则如果D == 0
计算两个相等的实根
输出一个根
否则
输出“无实根”
结束

5.用 N-S图表示第4题中各题的算法
略 ^_^

6.用伪代码表示第4题中各题的算法。
(1)
开始
  temp = A的内容
  A的内容 = B的内容
  B的内容 = temp
结束

(2)
开始
  max = 输入第一个数
  循环 i 从 2 到 10
    num = 输入下一个数
    如果 num > max
      max = num
    结束如果
  结束循环
  输出 max
结束

(3)
开始
  输入 a, b, c
  如果 a > b
    如果 a > c
      如果 b > c
        输出 a, b, c
      否则
        输出 a, c, b
      结束如果
    否则
      输出 c, a, b
    结束如果
  否则
    如果 b > c
      如果 a > c
        输出 b, a, c
      否则
        输出 b, c, a
      结束如果
    否则
      输出 c, b, a
    结束如果
结束

(4)
开始
  sum = 0
  循环 i 从 1 到 100
    sum = sum + i
  结束循环
  输出 sum
结束

(5)
开始
  输入 n
  如果 n mod 3 == 0 且 n mod 5 == 0
    输出 "能被3和5整除"
  否则
    输出 "不能被3和5整除"
  结束如果
结束

(6)
开始
  循环 num 从 100 到 200
    is_prime = 真
    循环 i 从 2 到 sqrt(num)
      如果 num mod i == 0
        is_prime = 假
        退出内循环
      结束如果
    结束循环
    如果 is_prime == 真
      输出 num
    结束如果
  结束循环
结束

(7)
开始
  输入 m, n
  当 n != 0
    temp = n
    n = m mod n
    m = temp
  结束当
  输出 m
结束

(8)
开始
  输入 a, b, c
  D = b^2 - 4ac
  如果 D > 0
    根1 = (-b + sqrt(D)) / (2a)
    根2 = (-b - sqrt(D)) / (2a)
    输出 根1, 根2
  否则如果 D == 0
    根 = -b / (2a)
    输出 根
  否则
    输出 "无实根"
  结束如果
结束



7.什么叫结构化程序设计?它的主要内容是什么?
**结构化程序设计**是一种编程范式,旨在提高程序的可读性、可维护性和可理解性。
它通过使用清晰的控制结构、模块化和自顶向下的设计方法,
帮助程序员开发出高质量的软件系统。

### 主要内容

1. **基本控制结构**:
   - **顺序结构**:程序按顺序逐行执行。
   - **选择结构**:根据条件的真假选择执行不同的代码路径(如if-else语句)。
   - **循环结构**:重复执行某段代码,直到满足特定条件(如for、while循环)。

2. **模块化设计**:
   - 将程序分解为独立的模块或函数,每个模块负责特定功能。
     这样可以提高代码的重用性和可维护性。

3. **自顶向下设计**:
   - 从高层次的概念开始,逐步细化到具体实现。
     这种方法使得程序的逻辑结构更加清晰。

4. **信息隐藏**:
   - 模块内部的实现细节对外部不可见,外部只需了解模块的接口。
     这有助于减少系统复杂性和提高安全性。

5. **代码规范**:
   - 采用统一的编码风格、注释和文档,使代码易于理解和维护。

### 结构化程序设计的优势

- **提高可读性**:清晰的结构使得程序易于理解,便于团队协作。
- **便于调试和测试**:模块化设计使得错误定位和单元测试更为简单。
- **增强可维护性**:更改和扩展功能时对其他部分影响较小。
- **促进代码重用**:模块化使得功能模块可以在多个项目中复用。

通过以上内容,结构化程序设计提供了一种系统化的方法来组织和编写代码,
确保软件的质量和可维护性。


8.用自顶向下、逐步细化的方法进行以下算法的设计:
(1)输出1900~2000年中是闰年的年份,符合下面两个条件之一的年份是闰年:
①能被4整除但不能被100整除;
②能被 100 整除且能被 400 整除。

顶层算法
输出1900到2000年间的闰年。

逐步细化
初始化年份范围为1900到2000。
对于每个年份:
如果年份满足闰年的条件:
条件1:能被4整除但不能被100整除。
条件2:能被100整除且能被400整除。
如果是闰年,则输出该年份。
开始
  对于 year 从 1900 到 2000
    如果 (year mod 4 == 0 且 year mod 100 != 0) 
    或 (year mod 100 == 0 且 year mod 400 == 0)
      输出 year
    结束如果
  结束循环
结束


(2)求ax^2+bx十c=0的根。分别考虑d=b*b-4ac大于0、等于0和小于0这3种情况。

顶层算法
计算方程的根。

逐步细化
输入系数a, b, c。
计算判别式 d = b² - 4ac。
根据判别式 d 的值判断根的情况:
如果 d > 0:
计算两个不等的实根。
如果 d == 0:
计算一个相等的实根。
如果 d < 0:
输出“无实根”。
开始
  输入 a, b, c
  d = b² - 4 * a * c
  如果 d > 0
    root1 = (-b + sqrt(d)) / (2 * a)
    root2 = (-b - sqrt(d)) / (2 * a)
    输出 root1, root2
  否则如果 d == 0
    root = -b / (2 * a)
    输出 root
  否则
    输出 "无实根"
  结束如果
结束


(3)输入10个数,输出其中最大的一个数。

顶层算法
找到10个数中的最大数。

逐步细化
初始化最大数为第一个输入数。
循环输入剩余9个数:
如果当前数大于最大数,则更新最大数。
输出最大数。
开始
  输入第一个数,max = 第一个数
  对于 i 从 2 到 10
    输入 num
    如果 num > max
      max = num
    结束如果
  结束循环
  输出 max
结束

第3章 顺序程序设计

1.假如我国国民生产总值的年增长率为9%,计算10年后我国国民生产总值与现在相
比增长多少百分比.
 计算公式为:p=(1十r)^nr为年增长率,n为年数,p为与现在相比的倍数)
#include <stdio.h>
#include <math.h>

int main() {
    double r = 0.09; // 年增长率
    int n = 10; // 年数
    double p = pow(1 + r, n); // 计算与现在相比的倍数
    // pow(2, 3) 即2的3次方

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

    printf("10年后国民生产总值增长百分比: %.2f%%\n", growth_percentage);
    return 0;
}
2.存款利息的计算。有1000元,想存5年,可按以下5种办法存:
(1)一次存5年期。
(2)先存2年期,到期后将本息再存3年期,
(3)先存3年期,到期后将本息再存2年期,
(4)存1年期,到期后将本息再存1年期,连续存5次。
(5)存活期存款。活期利息每一季度结算一次。
2007年12月的银行存款利息如下:

1年期定期存款利息为4.14%;
2年期定期存款利息为4.68%;
3年期定期存款利息为5.4%;
5年期定期存款利息为5.85%;

活期存款利息为0.72%(活期存款每一季度结算一次利息)
如果r为年利率,n为存款年数,则计算本息和的公式为
1年期本息和:P=1000*(1十r);
n年期本息和:P=1000*(1十n*r);
存n次1年期的本息和:P=1000*(1+r)^n;
活期存款本息和:P=1000*(1+r/4)^(4n)。
说明:1000*(1+r/4)是一个季度的本息和。
#include <stdio.h>
#include <math.h>

int main() {
    double principal = 1000.0; // 初始本金
    double P1, P2, P3, P4, P5;

    // (1) 一次存5年期
    double r1 = 0.0585;
    P1 = principal * (1 + r1); // 5年期本息和

    // (2) 先存2年期,到期后将本息再存3年期
    double r2 = 0.0468;
    double amount_after_2_years = principal * (1 + r2 * 2);
    double r3 = 0.054;
    P2 = amount_after_2_years * (1 + r3 * 3); // 3年期本息和

    // (3) 先存3年期,到期后将本息再存2年期
    double r4 = 0.054;
    double amount_after_3_years = principal * (1 + r4 * 3);
    double r5 = 0.0468;
    P3 = amount_after_3_years * (1 + r5 * 2); // 2年期本息和

    // (4) 存1年期,到期后将本息再存1年期,连续存5次
    double r6 = 0.0414;
    P4 = principal * pow(1 + r6, 5); // 1年期连续存5次的本息和

    // (5) 存活期存款,每季度结算一次
    double r7 = 0.0072; // 活期年利率
    P5 = principal * pow(1 + r7 / 4, 4 * 5); // 活期存款本息和

    // 输出结果
    printf("一次存5年期的本息和: %.2f\n", P1);
    printf("先存2年期再存3年期的本息和: %.2f\n", P2);
    printf("先存3年期再存2年期的本息和: %.2f\n", P3);
    printf("存1年期连续5次的本息和: %.2f\n", P4);
    printf("活期存款的本息和: %.2f\n", P5);

    return 0;
}
3.购房从银行贷了一笔款d,准备每月还款额为p,月利率为r,计算多少月能还清。设
d为300000元,p为6000元,r为1%。对求得的月份取小数点后一位,对第2位按四舍五
入处理。
提示:计算还清月数m的公式如下:

m= ( log(p) - log(p-d*r) ) / log(1+r)
可以将公式改写为:
m=( log( p / (p - d*r) ) ) / log(1+r)
C的库函数中有求对数的函数log10,是求以10为底的对数,log(p)表示 logp。
#include <stdio.h>
#include <math.h>

int main() {
    double d = 300000.0; // 贷款金额
    double p = 6000.0;   // 每月还款额
    double r = 0.01;     // 月利率

    // 计算月数 m
    double m = log10(p / (p - d * r)) / log10(1 + r);
    
    // 取小数点后一位,四舍五入
    double rounded_m = round(m * 10) / 10.0;

    printf("还清所需的月份: %.1f\n", rounded_m);

    return 0;
}
4.分析下面的程序:
# include <stdio.h>
int main( )
{
    char c1,c2;
    c1=97;
    c2=98;
    printf("c1=%c,c2=%c\n",c1,c2);
    printf("c1=%d,c2=%d\n",c1,c2);
    return 0;
}


(1)运行时会输出什么信息?为什么?

c1=a,c2=b
c1=97,c2=98


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

c1=ý,c2=Þ
c1=-59,c2=-58
在扩展ASCII表中:

197 对应的字符是 Ý(大写Y带重音符)。
198 对应的字符是 Þ(大写Thorn)。


197 的二进制是 11000101,
当解释为有符号数时,最左边的位是符号位(1表示负数)。
计算其补码形式:
补码计算:11000101 的补码为 00111011,对应的十进制值是 -59。

198 的二进制是 11000110,
同样处理为有符号数:
补码计算:11000110 的补码为 00111010,对应的十进制值是 -58。


(3)如果将程序第3行改为
int c1 ,c2;
运行时会输出什么信息?为什么?

c1=?c2=
c1=-59,c2=-58
5.用下面的scanf函数输入数据,使a=3,b=7,x=8.5,y=71.82,c1='A',c2='a'。
问在键盘上如何输入?
#include <stdio.h>
int main() {
    int a,b;
    float x,y;
    char c1,c2;
    scanf("a=%d,b=%d",&a,&b);
    scanf("%f%e",&a,&y);
    scanf("%c%c",&c1,&c2);
    return 0;
}
a=3,b=7
8.5 71.82
A a
6.请编程序将“China"译成密码,密码规律是:用原来的字母后面第4个字母代替原来
的字母。例如,字母“A”后面第4个字母是“E”,用“E”代替“A”。因此,“China”应译为
“Glmre”。请编一程序,用赋初值的方法使c1,c2,c3,c4,c5这5个变量的值分别为'C'
'h','i','n','a',经过运算,使c1,c2,c3,c4,c5 分别变为'G','l','m',r',e'。分别用 putchar
函数和printf函数输出这5个字符。
#include <stdio.h>

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

    // 进行替换
    c1 = c1 + 4;
    c2 = c2 + 4;
    c3 = c3 + 4;
    c4 = c4 + 4;
    c5 = c5 + 4;

    // 使用 putchar 输出
    putchar(c1);
    putchar(c2);
    putchar(c3);
    putchar(c4);
    putchar(c5);
    putchar('\n');  // 换行

    // 使用 printf 输出
    printf("输出结果为:%c%c%c%c%c\n", c1, c2, c3, c4, c5);

    return 0;
}
 7.设圆半径 r=1.5,圆柱高 h=3,求圆周长、圆面积、圆球表面积、圆球体积、圆柱体积。用scanf输入数据,输出计算结果,输出时要求有文字说明,取小数点后2位数字。请编程序。
#include <stdio.h>

#define PI 3.14159

int main() {
    float r, h;
    
    // 输入半径和高度
    printf("请输入圆的半径 r: ");
    scanf("%f", &r);
    printf("请输入圆柱的高 h: ");
    scanf("%f", &h);

    // 计算圆周长、圆面积、圆球表面积、圆球体积、圆柱体积
    float circumference = 2 * PI * r;                   // 圆周长
    float area = PI * r * r;                            // 圆面积
    float sphere_surface_area = 4 * PI * r * r;        // 圆球表面积
    float sphere_volume = (4.0 / 3.0) * PI * r * r * r; // 圆球体积
    float cylinder_volume = PI * r * r * h;            // 圆柱体积

    // 输出计算结果,保留两位小数
    printf("圆的周长: %.2f\n", circumference);
    printf("圆的面积: %.2f\n", area);
    printf("圆球的表面积: %.2f\n", sphere_surface_area);
    printf("圆球的体积: %.2f\n", sphere_volume);
    printf("圆柱的体积: %.2f\n", cylinder_volume);

    return 0;
}
8.编程序,用 getchar函数读入两个字符给c1和c2,然后分别用putchar 函数和 printf 函数输出这两个字符。思考以下问题:
#include <stdio.h>

int main() {
    char c1, c2;

    // 读取两个字符
    printf("请输入两个字符: ");
    c1 = getchar(); // 读入第一个字符
    c2 = getchar(); // 读入第二个字符

    // 输出字符
    printf("使用 putchar 输出:\n");
    putchar(c1);
    putchar('\n');
    putchar(c2);
    putchar('\n');

    printf("使用 printf 输出:\n");
    printf("%c\n", c1);
    printf("%c\n", c2);

    // 输出 ASCII 码
    printf("c1 的 ASCII 码: %d\n", c1);
    printf("c2 的 ASCII 码: %d\n", c2);

    return 0;
}


(1)变量c1和c2应定义为字符型还是整型?或二者皆可?

应该定义为字符型(char)。
虽然可以使用整型(int)来存储字符的ASCII值,
但如果只用来存储字符,使用字符型更合适且语义清晰。


(2)要求输出c1和c2值的ASCII码,应如何处理?用putchar函数还是 printf函数?

应该使用 printf 函数输出 ASCII 码,
因为 putchar 主要用于输出字符,
而 printf 可以格式化输出整型值(ASCII 码)。
示例代码中使用 %d 格式说明符输出ASCII值。


(3)整型变量与字符变量是否在任何情况下都可以互相代替?如:
char c1,c2;  与  int c1,c2;
是否无条件地等价?

不可以。
虽然在某些情况下,字符变量可以被隐式转换为整型(例如,存储ASCII值),
但是它们并不等价。
例如,char 通常占用1个字节,而 int 通常占用4个字节(具体取决于系统)。
因此,使用 char 变量更节省内存,并且更符合表示单个字符的意图。
使用 int 变量可能会导致不必要的复杂性和内存浪费。

第4章 选择结构程序设计

1.什么是算术运算?什么是关系运算?什么是逻辑运算?
以下是对算术运算、关系运算和逻辑运算的详细解释:

(1)算术运算
算术运算是基本的数学操作,主要用于数值计算。常见的算术运算包括:

加法 (+):
将两个数相加。例如:3 + 5 = 8

减法 (−):
从一个数中减去另一个数。例如:7 - 2 = 5

乘法 (×):
将两个数相乘。例如:4 × 6 = 24

除法 (÷):
将一个数除以另一个数。例如:20 ÷ 4 = 5

取余 (%):
计算一个数除以另一个数后的余数。例如:10 % 3 = 1

(2)关系运算
关系运算用于比较两个值之间的关系,通常返回布尔值(真或假)。常见的关系运算符包括:

等于 (==):
检查两个值是否相等。例如:5 == 5 返回真。

不等于 (!=):
检查两个值是否不相等。例如:3 != 4 返回真。

大于 (>):
检查一个值是否大于另一个值。例如:7 > 2 返回真。

小于 (<):
检查一个值是否小于另一个值。例如:3 < 5 返回真。

大于等于 (>=):
检查一个值是否大于或等于另一个值。例如:5 >= 5 返回真。

小于等于 (<=):
检查一个值是否小于或等于另一个值。例如:2 <= 4 返回真。

(3)逻辑运算
逻辑运算用于操作布尔值(真或假),主要用于条件判断和控制流。
常见的逻辑运算符包括:

与 (AND):仅当两个条件都为真时返回真。
例如:true AND true 返回真;true AND false 返回假。

或 (OR):只要有一个条件为真就返回真。
例如:true OR false 返回真;false OR false 返回假。

非 (NOT):将布尔值取反。
例如:NOT true 返回假;NOT false 返回真。

2.C语言中如何表示“真”和“假”?系统如何判断一个量的“真”和“假”?
在C语言中,`true` 表示“真”,而 `false` 表示“假”,
这通常需要包含 `<stdbool.h>` 头文件。

系统判断一个量的“真”和“假”通常基于其值:
非零值被视为“真”,零值被视为“假”。
例如,在条件语句中,`if (x)` 会在 `x` 非零时执行。

3.写出下面各逻辑表达式的值。设a=3,b=4,c=5。
(1) a+b>c && b==c
 ( 3 + 4 > 5 ) (真) 且 ( 4 == 5 ) (假) → 假


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

 ( 3 || 4 + 5 && 4 - 5 ) → ( 3 || 9 && -1 ) → ( 3 || 9 ) (真) → 真


(3) !(a>b) && !c || 1

 ( !(3 > 4) && !5 || 1 ) → 真且假 || 真 → 真


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

由于 ( !(x = 3) ) 是假,所以整个表达式为假。


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

( !(3 + 4) + 5 - 1 && 4 + 5 / 2 ) → 假 + 4 (真) → 真

4.有3个整数a,b,c,由键盘输人,输出其中最大的数。
#include <stdio.h>

int main() {
    int a, b, c;
    
    // 输入三个整数
    printf("请输入三个整数: ");
    scanf("%d %d %d", &a, &b, &c);
    
    // 假设a是最大的
    int max = a;

    // 判断b是否比max大
    if (b > max) {
        max = b;
    }
    
    // 判断c是否比max大
    if (c > max) {
        max = c;
    }

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

    return 0;
}

5.从键盘输入一个小于1000的正数,要求输出它的平方根(如平方根不是整数,则输出其整数部分)。要求在输人数据后先对其进行检查是否为小于1000的正数。若不是,则要求重新输入。
#include <stdio.h>
#include <math.h>

int main() {
    double number;
    
    while (1) {
        // 输入一个小于1000的正数
        printf("请输入一个小于1000的正数: ");
        scanf("%lf", &number);
        
        // 检查输入的数是否符合条件
        if (number > 0 && number < 1000) {
            // 计算平方根并输出其整数部分
            int sqrt_int = (int)sqrt(number);
            printf("该数的平方根的整数部分是: %d\n", sqrt_int);
            break;  // 输入有效,退出循环
        } else {
            printf("输入无效,请确保输入的是一个小于1000的正数。\n");
        }
    }

    return 0;
}
 6.有一个函数: 如图

 写程序,输入x的值,输出y相应的值。

#include <stdio.h>

int main() {
    double x, y;

    // 输入x的值
    printf("请输入x的值: ");
    scanf("%lf", &x);

    // 根据条件计算y的值
    if (x < 1) {
        y = x;
    } else if (x >= 1 && x < 10) {
        y = 2 * x - 1;
    } else { // x >= 10
        y = 3 * x - 11;
    }

    // 输出y的值
    printf("y的值为: %.2f\n", y);

    return 0;
}
7.有一函数:如图

有人分别编写了以下两个程序,请分析它们是否能实现题目要求。不要急于上机运行
程序,先分析上面两个程序的逻辑,画出它们的流程图,分析它们的运行情况。然后上机运
行程序,观察和分析结果,
 

 

自己上机敲代码咯 ^_^
8.给出一百分制成绩,要求输出成绩等级'A'、'B'、'C'、'D'、'E'。
90分以上为'A',
80~89 为'B',
70~79 分为'C',
60~69 分为'D',
60分以下为'E'。
#include <stdio.h>

int main() {
    int score;

    // 输入成绩
    printf("请输入成绩(0-100):");
    scanf("%d", &score);

    // 判断成绩等级
    if (score >= 90 && score <= 100) {
        printf("成绩等级: A\n");
    } else if (score >= 80 && score < 90) {
        printf("成绩等级: B\n");
    } else if (score >= 70 && score < 80) {
        printf("成绩等级: C\n");
    } else if (score >= 60 && score < 70) {
        printf("成绩等级: D\n");
    } else if (score >= 0 && score < 60) {
        printf("成绩等级: E\n");
    } else {
        printf("输入无效,请输入0到100之间的成绩。\n");
    }

    return 0;
}
9.给一个不多于5位的正整数,要求:
求出它是几位数;
分别输出每一位数字;
按逆序输出各位数字,例如原数为321,应输出123。
#include <stdio.h>

int main() {
    int number, temp, digits = 0;
    int digitsArray[5];

    // 输入不多于5位的正整数
    printf("请输入一个不多于5位的正整数: ");
    scanf("%d", &number);

    // 检查输入是否有效
    if (number < 1 || number > 99999) {
        printf("输入无效,请输入一个正整数,不超过5位。\n");
        return 1;
    }

    // 计算位数和各位数字
    temp = number;
    while (temp > 0) {
        digitsArray[digits] = temp % 10; // 提取各位数字
        temp /= 10;                       // 去掉最后一位
        digits++;
    }

    // 输出位数
    printf("该数是 %d 位数。\n", digits);

    // 输出每一位数字
    printf("各位数字为: ");
    for (int i = digits - 1; i >= 0; i--) {
        printf("%d ", digitsArray[i]);
    }
    printf("\n");

    // 按逆序输出各位数字
    printf("逆序输出: ");
    for (int i = 0; i < digits; i++) {
        printf("%d", digitsArray[i]);
    }
    printf("\n");

    return 0;
}
10.企业发放的奖金根据利润提成。
利润I低于或等于100000元的,奖金可提10%;
利润高于 100000元,低于200000元(100000<I<=200000)时,低于100000元的部分按10%提成,
高于100000元的部分,可提成7.5%;200000<I<=400000时,低于200000元的部分仍按上述办法提成(下同)。高于200000元的部分按5%提成;
400000<I<=600000元时,高于 400000元的部分按3%提成;
600000<I<=1000000时,高于600000元的部分按1.5%提成;
I>1000000时,超过1000000元的部分按1%提成。

从键盘输入当月利润I,求应发奖金总数。
要求:
(1)用if语句编程序;
#include <stdio.h>

int main() {
    double profit, bonus = 0.0;

    // 输入利润
    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("应发奖金总数: %.2f 元\n", bonus);
    return 0;
}


(2)用 switch 语句编程序。

#include <stdio.h>

int main() {
    double profit, bonus = 0.0;

    // 输入利润
    printf("请输入当月利润: ");
    scanf("%lf", &profit);

    // 根据利润区间计算奖金
    int profitRange = 0; // 0: <= 100000, 1: 100001 - 200000, 2: 200001 - 400000, 3: 400001 - 600000, 4: 600001 - 1000000, 5: > 1000000

    if (profit <= 100000) {
        profitRange = 0;
    } else if (profit <= 200000) {
        profitRange = 1;
    } else if (profit <= 400000) {
        profitRange = 2;
    } else if (profit <= 600000) {
        profitRange = 3;
    } else if (profit <= 1000000) {
        profitRange = 4;
    } else {
        profitRange = 5;
    }

    switch (profitRange) {
        case 0:
            bonus = profit * 0.1;
            break;
        case 1:
            bonus = 100000 * 0.1 + (profit - 100000) * 0.075;
            break;
        case 2:
            bonus = 100000 * 0.1 + 100000 * 0.075 + (profit - 200000) * 0.05;
            break;
        case 3:
            bonus = 100000 * 0.1 + 100000 * 0.075 + 200000 * 0.05 + (profit - 400000) * 0.03;
            break;
        case 4:
            bonus = 100000 * 0.1 + 100000 * 0.075 + 200000 * 0.05 + 200000 * 0.03 + (profit - 600000) * 0.015;
            break;
        case 5:
            bonus = 100000 * 0.1 + 100000 * 0.075 + 200000 * 0.05 + 200000 * 0.03 + 400000 * 0.015 + (profit - 1000000) * 0.01;
            break;
        default:
            printf("输入无效。\n");
            return 1;
    }

    // 输出奖金
    printf("应发奖金总数: %.2f 元\n", bonus);
    return 0;
}
11.输入4个整数,要求按由小到大的顺序输出.
#include <stdio.h>

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

    // 使用简单的排序算法(冒泡排序)
    int nums[4] = {a, b, c, d};
    for (int i = 0; i < 4; i++) {
        for (int j = 0; j < 3 - i; j++) {
            if (nums[j] > nums[j + 1]) {
                // 交换
                int temp = nums[j];
                nums[j] = nums[j + 1];
                nums[j + 1] = temp;
            }
        }
    }

    // 输出排序后的结果
    printf("按由小到大的顺序输出: ");
    for (int i = 0; i < 4; i++) {
        printf("%d ", nums[i]);
    }
    printf("\n");

    return 0;
}
12.有4个圆塔,圆心分别为(2,2)、(一2,2)、(一2,一2)、(2,一2),圆半径为1,见图。这4个塔的高度为10m,塔以外无建筑物。今输入任一点的坐标,求该点的建筑高度(塔外的高度为零)

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

int main() {
    double x, y;
    double height = 10.0; // 圆塔高度
    double radius = 1.0;   // 圆塔半径

    // 输入点的坐标
    printf("请输入点的坐标 (x, y): ");
    scanf("%lf %lf", &x, &y);

    // 判断点是否在任意一个圆塔内
    int insideTower = 0; // 标记是否在圆塔内

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

    for (int i = 0; i < 4; i++) {
        double dx = x - centers[i][0];
        double dy = y - centers[i][1];
        if (dx * dx + dy * dy <= radius * radius) {
            insideTower = 1; // 在圆塔内
            break;
        }
    }

    // 输出结果
    if (insideTower) {
        printf("该点的建筑高度为: %.2f m\n", height);
    } else {
        printf("该点的建筑高度为: 0 m\n");
    }

    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值