以下答案和解析是根据《C程序设计(第四版)》(作者:谭浩强)的常见练习题编写的,由于不同版本或印刷批次可能存在细微差别,题目序号或内容可能不完全一致。请务必将此作为参考,结合您自己的题目进行核对。 学习编程的关键在于理解思路和动手实践,直接抄写答案无法提升编程能力。

(图片来源网络,侵删)
第四章 选择结构
本章主要介绍 if 语句和 switch 语句,用于实现程序的选择分支逻辑。
1 写出以下程序的运行结果
1:**
#include <stdio.h>
int main()
{
int a, b, c;
a = 10; b = 20; c = 30;
if (c > b > a)
printf("A\n");
else
printf("B\n");
return 0;
}
答案与解析: 运行结果:B
解析:
这道题考察的是C语言中关系表达式的求值规则,表达式 c > b > a 并不像数学中那样直接判断 c 是否大于 b 且 b 是否大于 a。

(图片来源网络,侵删)
在C语言中,关系运算符(如 >)是从左到右结合的。c > b > a 实际上被解释为 (c > b) > a。
- 首先计算
c > b:30 > 20,结果为真(1)。 - 然后计算
1 > a:1 > 10,结果为假(0)。 - 整个表达式的最终结果是
0(假)。 if判断条件为假,因此执行else分支的代码,输出B。
2 写出以下程序的运行结果
2:**
#include <stdio.h>
int main()
{
int x = 1, y = 1, z = 1;
if (x = y + z)
printf("****\n");
else
printf("####\n");
return 0;
}
答案与解析: 运行结果:**
解析:
这道题考察的是 if 语句中的条件判断,特别是赋值表达式与逻辑表达式的区别。

(图片来源网络,侵删)
if语句括号里的内容是x = y + z,这是一个赋值表达式,而不是一个逻辑判断表达式x == y + z。- 赋值表达式本身也有一个值,其值就是被赋的值。
- 首先计算右边的
y + z:1 + 1 = 2。 - 然后将
2赋给x,x的值变为2。 - 赋值表达式
x = y + z的值为2。 if语句判断的是这个表达式的值,在C语言中,非零的值代表“真”(True),0代表“假”(False)。- 因为
2是非零值,所以条件为真,执行if分支的代码,输出 。
3 写出以下程序的运行结果
3:**
#include <stdio.h>
int main()
{
int a, b, c;
a = b = c = 1;
++a || ++b && ++c;
printf("%d, %d, %d\n", a, b, c);
return 0;
}
答案与解析: 运行结果:2, 1, 1
解析: 这道题考察的是逻辑运算符的短路特性和优先级。
a = b = c = 1;:将a,b,c都初始化为1。++a || ++b && ++c;:这是一个逻辑表达式。- 优先级:
&&的优先级高于 ,所以这个表达式等价于++a || (++b && ++c)。 - 短路特性:对于 运算符,如果左边的表达式为真,整个表达式的值就为真,右边的表达式不会被执行。
- 优先级:
- 从左到右计算:
- 先计算
++a:a的值自增为2,表达式的值为2(真)。 - 因为 的左边已经是真,根据短路特性,整个表达式已经确定为真,因此右边的
++b && ++c完全不会被执行。 b和c的值保持不变,仍然是1。
- 先计算
a的值为2,b的值为1,c的值为1,程序输出2, 1, 1。
4 编程题
1:** 有一个函数 y = f(x),用以下公式定义:
x (x < 1)
y = 2x - 1 (1 <= x < 10)
3x - 11 (x >= 10)
写一个程序,输入 x,输出 y。
参考代码与解析:
#include <stdio.h>
int main()
{
double x, y;
printf("请输入x的值: ");
scanf("%lf", &x);
if (x < 1) {
y = x;
} else if (x < 10) { // 这个条件隐含了 x >= 1
y = 2 * x - 1;
} else { // 这个条件隐含了 x >= 10
y = 3 * x - 11;
}
printf("y的值为: %f\n", y);
return 0;
}
解析:
- 分析:这是一个典型的分段函数问题,需要根据
x的不同取值范围来计算y。if-else if-else结构是解决这类问题的标准方法。 - 输入:使用
double类型来存储x和y,以支持小数输入。scanf使用%lf来读取double类型。 - 判断逻辑:
- 第一个
if (x < 1)检查x是否在第一个区间。 - 如果不在,用
else if (x < 10)检查是否在第二个区间,注意,这里不需要再写x >= 1,因为如果程序执行到这里,说明x < 1的条件已经为假。 - 如果前两个条件都不满足,则必然是
x >= 10的情况,使用else分支处理。
- 第一个
- 输出:使用
%f来打印double类型的变量。
2:** 给一个不多于5位的正整数,要求:①求它是几位数;②分别打印出每一位数字;③按逆序打印出各位数字。
参考代码与解析:
#include <stdio.h>
int main()
{
int num, originalNum, digitCount = 0;
int digits[5]; // 用于存储每一位数字
printf("请输入一个不多于5位的正整数: ");
scanf("%d", &num);
if (num <= 0 || num > 99999) {
printf("输入无效,请输入一个1到99999之间的正整数,\n");
return 1; // 非正常退出
}
originalNum = num; // 保存原始数字用于逆序输出
// ① 求它是几位数,并分离每一位数字
while (num > 0) {
digits[digitCount] = num % 10; // 取出最后一位
num /= 10; // 去掉最后一位
digitCount++;
}
// ② 分别打印出每一位数字 (正序)
printf("① 这是一个 %d 位数,\n", digitCount);
printf("② 每一位数字分别是: ");
for (int i = digitCount - 1; i >= 0; i--) {
printf("%d ", digits[i]);
}
printf("\n");
// ③ 按逆序打印出各位数字
printf("③ 逆序数字是: ");
for (int i = 0; i < digitCount; i++) {
printf("%d ", digits[i]);
}
printf("\n");
return 0;
}
解析:
- 输入验证:首先检查输入的数字是否在有效范围内(1到99999)。
- 核心算法(分离数字):
- 使用
while循环来处理数字。 num % 10:取余运算,可以得到num的最后一位数字。num /= 10:整数除法,会去掉num的最后一位。- 循环的次数就是数字的位数,我们用一个
digitCount变量来计数。 - 为了方便后续打印,我们将取出的每一位数字存入一个数组
digits中,注意,存入的是逆序的(数字123存入的顺序是3, 2, 1)。
- 使用
- 输出结果:
- ① 位数:
digitCount变量在循环结束后就保存了数字的位数。 - ② 正序打印:因为数组里是逆序存储的,所以从数组的末尾向前遍历,就可以得到正序的数字。
- ③ 逆序打印:直接按数组存储的顺序(从前往后)遍历打印即可。
- ① 位数:
