
- 版本确认:不同出版社、不同作者编写的《C语言程序设计教程(第二版)》其课后习题内容可能存在差异,以下答案是基于谭浩强老师的《C语言程序设计教程(第二版)》,这是国内最经典、使用最广泛的版本之一,如果您的教材版本不同,题目顺序或内容可能略有出入,但核心知识点和解题思路是相通的。
- 目的:提供答案是为了帮助您学习和理解,而不是为了直接抄袭,请务必自己先思考、编写代码,然后再对照答案,分析自己的不足之处。
- 代码风格:答案中的代码遵循了良好的编程风格,包括清晰的注释、合理的变量命名和代码缩进,建议您在学习时也模仿这种风格。
- 持续更新:由于篇幅限制,我将先提供前几章的典型题目答案,并持续更新,如果您有特定章节的题目需要解答,可以随时提出。
第一章 C语言概述
本章主要是基础概念,通常以简答题和选择题为主,不涉及编程题。
1 什么是结构化程序设计?它的主要特点是什么?
答:
结构化程序设计是一种面向过程的程序设计方法,它主张使用顺序、选择、循环这三种基本结构来构建程序,以避免使用goto语句造成的程序流程混乱。
其主要特点包括:

- 自顶向下:将一个复杂的大问题分解成若干个相对独立的小问题,然后再将小问题分解成更小的问题,逐步细化。
- 逐步求精:对每一个层次的问题,逐步设计出具体的实现方法,直到能用某种编程语言描述为止。
- 模块化:将程序分解成若干个功能独立的模块(即函数),每个模块负责完成一个特定的功能。
- 限制使用
goto语句:因为goto语句会使程序流程混乱,难以理解和维护。
2 C语言的主要特点是什么?
答: C语言的主要特点可以概括为以下几点:
- 语言简洁、紧凑,使用方便、灵活:C语言一共只有32个关键字和9种控制语句,程序书写形式自由。
- 运算符丰富:C语言共有34种运算符,包含了算术、关系、逻辑、位、赋值、指针等多种运算符,表达式类型多样。
- 数据结构丰富:C语言的数据类型有整型、实型、字符型、数组、指针、结构体、共用体等,能实现各种复杂的数据结构。
- 结构化语言:C语言是典型的结构化语言,具有顺序、选择、循环三种基本结构,便于模块化程序设计。
- 可移植性好:C语言程序通常对硬件依赖性较低,经过少量修改甚至无需修改就可以在不同的操作系统和硬件平台上运行。
- 生成目标代码质量高,程序执行效率高:C语言可以直接操作硬件,其代码效率仅次于汇编语言。
- 可以直接操作硬件:C语言具有低级语言(如汇编语言)的一些特性,如指针操作、位操作等,能直接访问内存地址,进行底层操作。
第二章 数据类型、运算符与表达式
本章是C语言的基础,重点在于掌握各种数据类型、运算符的优先级和结合性。
1 请将以下数学表达式写成C语言表达式。

- (1)
a = (b + c) * d - (2)
s = 3.14 * r * r - (3)
y = |x| + 5(使用库函数fabs)y = fabs(x) + 5;
- (4)
x1 = (-b + sqrt(b*b - 4*a*c)) / (2*a)x1 = (-b + sqrt(b*b - 4*a*c)) / (2.0*a);(注意分母用2.0以保证浮点数除法)
2 写出以下程序的运行结果。
#include <stdio.h>
int main() {
int a, b, c;
a = 10; b = 20; c = 30;
printf("%d, %d, %d\n", a, b, c);
c = a + b;
a = a * 2;
b = b / 2;
printf("%d, %d, %d\n", a, b, c);
return 0;
}
答: 程序运行结果为:
10, 20, 30
20, 10, 30
解析:
- 第一条
printf语句直接输出初始值:a=10, b=20, c=30。 - 然后执行赋值操作:
c = a + b;c的值变为10 + 20 = 30。a = a * 2;a的值变为10 * 2 = 20。b = b / 2;b的值变为20 / 2 = 10。
- 第二条
printf语句输出更新后的值:a=20, b=10, c=30。
3 写出以下程序的运行结果。
#include <stdio.h>
int main() {
int i, j, m, n;
i = 8; j = 10;
m = ++i; n = j++;
printf("%d, %d, %d, %d\n", i, j, m, n);
return 0;
}
答: 程序运行结果为:
9, 11, 9, 10
解析: 这是考察自增运算符()的前置和后置区别。
i = 8; j = 10;初始化。m = ++i;前置自增:i先自增变为9,然后将i的新值9赋给m,执行后,i=9, m=9。n = j++;后置自增:先将j的当前值10赋给n,然后j再自增变为11,执行后,j=11, n=10。printf输出四个变量的最终值:i=9, j=11, m=9, n=10。
第三章 顺序结构程序设计
本章主要练习基本输入输出函数scanf和printf的使用。
1 编写程序,从键盘输入两个整数,计算它们的和、差、积、商,并输出结果。
答:
#include <stdio.h>
int main() {
int num1, num2;
int sum, difference, product;
float quotient; // 商可能是小数,所以用float类型
// 提示用户输入
printf("请输入两个整数,用空格隔开: ");
// 从键盘读取两个整数
// 注意:&是取地址符,scanf需要变量的地址
scanf("%d %d", &num1, &num2);
// 进行计算
sum = num1 + num2;
difference = num1 - num2;
product = num1 * num2;
quotient = (float)num1 / num2; // 强制类型转换,确保得到浮点数结果
// 输出结果
printf("它们的和是: %d\n", sum);
printf("它们的差是: %d\n", difference);
printf("它们的积是: %d\n", product);
printf("它们的商是: %.2f\n", quotient); // %.2f表示输出两位小数
return 0;
}
2 编写程序,输入一个小写字母,输出其对应的大写字母。
答:
#include <stdio.h>
int main() {
char lowercase_char, uppercase_char;
printf("请输入一个小写字母: ");
// 使用 %c 读取一个字符
scanf("%c", &lowercase_char);
// 核心算法:小写字母的ASCII码比大写字母大32
// 'a' - 'A' = 97 - 65 = 32
uppercase_char = lowercase_char - 32;
printf("对应的大写字母是: %c\n", uppercase_char);
return 0;
}
第四章 选择结构程序设计
本章重点练习if-else、if-else if-else以及switch语句。
1 编写程序,输入一个整数,判断它是奇数还是偶数。
答:
#include <stdio.h>
int main() {
int number;
printf("请输入一个整数: ");
scanf("%d", &number);
// 使用取模运算符 %,number % 2 的余数为0,则是偶数,否则是奇数
if (number % 2 == 0) {
printf("%d 是一个偶数,\n", number);
} else {
printf("%d 是一个奇数,\n", number);
}
return 0;
}
2 编程实现:根据输入的学生成绩,输出其等级。
- 90-100: A
- 80-89: B
- 70-79: C
- 60-69: D
- 60以下: E
答:
使用if-else if-else结构非常合适。
#include <stdio.h>
int main() {
float score;
char grade;
printf("请输入学生的成绩 (0-100): ");
scanf("%f", &score);
// 对输入进行有效性检查
if (score < 0 || score > 100) {
printf("输入的成绩无效!\n");
return 1; // 非正常退出
}
// 判断等级
if (score >= 90) {
grade = 'A';
} else if (score >= 80) {
grade = 'B';
} else if (score >= 70) {
grade = 'C';
} else if (score >= 60) {
grade = 'D';
} else {
grade = 'E';
}
printf("成绩等级为: %c\n", grade);
return 0;
}
第五章 循环结构程序设计
本章练习for、while、do-while循环以及break和continue的使用。
1 求1到100之间所有偶数的和。
答:
#include <stdio.h>
int main() {
int sum = 0;
int i;
// 方法一:直接对偶数求和
for (i = 2; i <= 100; i += 2) {
sum += i;
}
printf("1到100之间所有偶数的和是: %d\n", sum);
return 0;
}
2 输入一行字符,分别统计其中英文字母、空格、数字和其他字符的个数。
答:
#include <stdio.h>
#include <ctype.h> // 用于字符分类函数
int main() {
char ch;
int letters = 0, spaces = 0, digits = 0, others = 0;
printf("请输入一行字符 (以回车结束):\n");
// 使用 getchar() 逐个读取字符,直到遇到换行符 '\n'
while ((ch = getchar()) != '\n') {
if (isalpha(ch)) { // 检查是否是字母
letters++;
} else if (isdigit(ch)) { // 检查是否是数字
digits++;
} else if (isspace(ch)) { // 检查是否是空格
spaces++;
} else { // 其他字符
others++;
}
}
printf("统计结果:\n");
printf("字母数量: %d\n", letters);
printf("数字数量: %d\n", digits);
printf("空格数量: %d\n", spaces);
printf("其他字符数量: %d\n", others);
return 0;
}
第六章 数组
本章是C语言的重点和难点,涉及一维数组、二维数组的定义、初始化和遍历。
1 用数组求斐波那契数列的前20项,斐波那契数列:1, 1, 2, 3, 5, 8, 13...
答:
#include <stdio.h>
int main() {
int fib[20]; // 定义一个包含20个整数的数组
int i;
// 初始化前两项
fib[0] = 1;
fib[1] = 1;
// 从第3项开始,用循环计算后续项
// fib[i] = fib[i-1] + fib[i-2]
for (i = 2; i < 20; i++) {
fib[i] = fib[i - 1] + fib[i - 2];
}
// 输出数组的所有元素
printf("斐波那契数列的前20项为:\n");
for (i = 0; i < 20; i++) {
printf("%d ", fib[i]);
// 每5个数换一行,使输出更美观
if ((i + 1) % 5 == 0) {
printf("\n");
}
}
return 0;
}
2 有一个已排好序的数组,要求输入一个数,把它插入到数组中,并保持数组仍然有序。
答:
#include <stdio.h>
int main() {
int a[11] = {1, 4, 6, 9, 13, 16, 19, 28, 40, 100}; // 已排序数组,留一个空位
int num, i, j, insert_pos = -1;
const int SIZE = 10; // 当前数组中有10个有效元素
printf("原始数组: ");
for (i = 0; i < SIZE; i++) {
printf("%d ", a[i]);
}
printf("\n");
printf("请输入要插入的整数: ");
scanf("%d", &num);
// 1. 找到插入的位置
for (i = 0; i < SIZE; i++) {
if (num < a[i]) {
insert_pos = i;
break;
}
}
// 如果所有数都比num小,则插入在末尾
if (insert_pos == -1) {
insert_pos = SIZE;
}
// 2. 从插入位置开始,后面的元素依次后移一位
for (j = SIZE; j > insert_pos; j--) {
a[j] = a[j - 1];
}
// 3. 将新数插入到找到的位置
a[insert_pos] = num;
// 4. 输出插入后的数组
printf("插入后的数组: ");
for (i = 0; i < SIZE + 1; i++) {
printf("%d ", a[i]);
}
printf("\n");
return 0;
}
第七章 函数
本章练习函数的定义、调用、参数传递(值传递)、返回值以及递归。
1 编写一个函数,判断一个数是否为素数(质数),并在main函数中调用它。
答:
#include <stdio.h>
#include <math.h> // 用于 sqrt 函数
// 函数声明
// is_prime 是一个函数,接收一个整型参数 num,返回一个整型结果(1表示是素数,0表示不是)
int is_prime(int num);
int main() {
int number;
printf("请输入一个正整数: ");
scanf("%d", &number);
if (number <= 1) {
printf("%d 不是素数,\n", number);
} else if (is_prime(number)) {
printf("%d 是一个素数,\n", number);
} else {
printf("%d 不是一个素数,\n", number);
}
return 0;
}
// 函数定义
int is_prime(int num) {
if (num == 2) {
return 1; // 2是素数
}
if (num % 2 == 0) {
return 0; // 排除所有偶数
}
// 只需要检查从3到sqrt(num)之间的奇数
for (int i = 3; i <= sqrt(num); i += 2) {
if (num % i == 0) {
return 0; // 如果能被整除,则不是素数
}
}
return 1; // 如果都不能被整除,则是素数
}
2 用递归方法计算 n!。
答: 递归的要点在于递归出口和递归调用。
- 递归出口:
0! = 1或1! = 1。 - 递归调用:
n! = n * (n-1)!。
#include <stdio.h>
// 函数声明
long factorial(int n);
int main() {
int n;
long result;
printf("请输入一个非负整数: ");
scanf("%d", &n);
if (n < 0) {
printf("错误:请输入一个非负整数,\n");
} else {
result = factorial(n);
printf("%d! = %ld\n", n, result);
}
return 0;
}
// 函数定义
long factorial(int n) {
// 递归出口
if (n == 0 || n == 1) {
return 1;
} else {
// 递归调用
return n * factorial(n - 1);
}
}
