
- 学习目的: 请务必将此答案用于学习、参考和验证思路,而不是简单地复制粘贴,直接抄答案无法真正掌握C语言编程。
- 版本差异: 不同印刷版本或地区的习题顺序和编号可能存在微小差异,请根据您手中的具体题目进行核对。
- 代码风格: 这些答案遵循了谭浩强教材中常见的风格(如使用
stdio.h,main()等),在实际工业开发中,可能会有更现代或规范的做法(如使用int main(void),包含stdlib.h等)。 - 持续更新: 这里包含的是一些非常经典和常见的题目,如果您有其他具体题目需要解答,欢迎随时提出,我会尽力为您解答。
第一章 C语言概述
本章主要是概念题,答案多为文字描述。
1 什么是程序?什么是程序设计?
- 程序: 是为完成某项任务而编写的一系列指令(代码)的集合,它告诉计算机如何一步步地执行特定操作。
- 程序设计: 是指为了解决某个特定问题,分析问题、设计算法、编写代码、调试测试并最终得到可执行程序的全过程。
2 为什么需要计算机语言?计算机语言有哪几种?
- 需要原因: 人与计算机交流需要一种双方都能理解的语言,计算机只能识别机器语言(二进制代码),直接编写非常困难,计算机语言提供了更接近人类思维和表达方式的工具,使得人们能够高效地指挥计算机工作。
- 种类:
- 机器语言: 计算机唯一能直接识别和执行的语言,由0和1组成。
- 汇编语言: 用助记符(如
MOV,ADD)代替机器指令,需要汇编器翻译成机器语言。 - 高级语言: 接近自然语言和数学语言,如 C, C++, Java, Python 等,需要编译器或解释器翻译成机器语言。
3 C语言有什么特点?

- 语言简洁、紧凑,使用方便灵活。
- 运算符丰富,共有34种运算符。
- 数据结构类型丰富。
- 具有结构化的控制语句(如
if-else,for,while)。 - 语法限制不太严格,程序设计自由度大。
- 允许直接访问物理地址,能进行位(bit)操作,可直接对硬件进行操作。
- 生成目标代码质量高,程序执行效率高。
- 可移植性好。
第二章 数据类型、运算符与表达式
本章是基础,需要大量练习。
5 将下列数学式子写成C语言表达式。
a = (b + c) / (d - e)a = (3 + x) / 5 - (y + 2) / 2a = sin(x) + cos(x)a = sqrt(pow(x, 2) + pow(y, 2))// 需要包含math.h库a = exp(x) * log(y)// 同样需要math.h
6 写出程序运行的结果。
#include <stdio.h>
int main() {
int i, j, m, n;
i = 8;
j = 10;
m = ++i; // i先自增变为9,再赋值给m,所以m=9, i=9
n = j++; // j先赋值给n,再自增,所以n=10, j=11
printf("%d, %d, %d, %d\n", i, j, m, n);
return 0;
}
答案:
9, 11, 9, 10
7 写出下面表达式运算后a的值,设原来a=12。
设 int a = 12;
a += a;//a = a + a;a = 24;a -= 2;//a = a - 2;a = 10;a *= 2 + 3;//a = a * (2 + 3);a = 12 * 5 = 60;a /= a + a;//a = a / (a + a);a = 12 / (12 + 12) = 12 / 24 = 0;(注意:整数除法)a %= 5;//a = a % 5;a = 12 % 5 = 2;
第三章 最简单的C程序设计
本章重点是输入输出函数。
6 写出以下程序的运行结果。
#include <stdio.h>
int main() {
char c1 = 'a', c2 = 'b', c3 = 'c', c4 = '\101', c5 = '\116';
printf("a%c b%c\tc%c\tabc\n", c1, c2, c3);
printf("\t\b%c %c\n", c4, c5);
return 0;
}
解析:
\101是八进制转义字符,等于十进制的 65,对应ASCII码的字符 'A'。\116是八进制转义字符,等于十进制的 78,对应ASCII码的字符 'N'。\t是横向跳格符。\b是退格符。
答案:
aab c abc
A N
7 要将 "China" 译成密码,译码规律是:用原来字母后面的第4个字母代替原来的字母,字母 'A' 后面第4个字母是 'E','E' 代替 'A'。"China" 应译为 "Glmre",请编写程序,用赋初值的方法使 c1, c2, c3, c4, c5 五个变量的值分别为 'C', 'h', 'i', 'n', 'a',经过运算,使 c1, c2, c3, c4, c5 分别变为 'G', 'l', 'm', 'r', 'e',并输出。
#include <stdio.h>
int main() {
char c1 = 'C', c2 = 'h', c3 = 'i', c4 = 'n', c5 = 'a';
// 每个字符的ASCII码值加4
c1 = c1 + 4;
c2 = c2 + 4;
c3 = c3 + 4;
c4 = c4 + 4;
c5 = c5 + 4;
printf("密码是: %c%c%c%c%c\n", c1, c2, c3, c4, c5);
return 0;
}
答案: 密码是: Glmre
第四章 逻辑运算和分支结构
本章是C语言的核心,if-else 和 switch 必须熟练掌握。
6 有一个函数: y = { x (x < 1) 2x-1 (1 ≤ x < 10) 3x-11 (x ≥ 10) } 写一程序,输入x,输出y值。
#include <stdio.h>
int main() {
float x, y;
printf("请输入x的值: ");
scanf("%f", &x);
if (x < 1) {
y = x;
} else if (x < 10) { // 1 ≤ x < 10
y = 2 * x - 1;
} else { // x ≥ 10
y = 3 * x - 11;
}
printf("y的值是: %f\n", y);
return 0;
}
7 给一个不多于5位的正整数,要求:
- 求它是几位数;
- 分别打印出每一位数字;
- 按逆序打印出各位数字。
#include <stdio.h>
int main() {
int num, temp, digits = 0;
int a, b, c, d, e; // 分别存放个、十、百、千、万位
printf("请输入一个不多于5位的正整数: ");
scanf("%d", &num);
if (num < 1 || num > 99999) {
printf("输入的数字不合法!\n");
return 1; // 非正常退出
}
temp = num;
// 1. 求位数
while (temp != 0) {
temp /= 10;
digits++;
}
printf("这是一个 %d 位数,\n", digits);
// 2. 分解各位数字
e = num / 10000;
d = (num % 10000) / 1000;
c = (num % 1000) / 100;
b = (num % 100) / 10;
a = num % 10;
printf("每一位数字分别是: ");
if (digits == 5) printf("%d ", e);
if (digits >= 4) printf("%d ", d);
if (digits >= 3) printf("%c ", c);
if (digits >= 2) printf("%d ", b);
printf("%d\n", a);
// 3. 逆序打印
printf("逆序打印为: ");
printf("%d", a);
if (digits >= 2) printf("%d", b);
if (digits >= 3) printf("%d", c);
if (digits >= 4) printf("%d", d);
if (digits == 5) printf("%d", e);
printf("\n");
return 0;
}
第五章 循环结构
循环结构是另一个核心,for, while, do-while 要灵活运用。
6 输出所有的“水仙花数”,所谓“水仙花数”是指一个3位数,其各位数字立方和等于该数本身,153是一个“水仙花数”,因为 153 = 1³ + 5³ + 3³。
#include <stdio.h>
int main() {
int i, a, b, c;
printf("所有的水仙花数是:\n");
for (i = 100; i <= 999; i++) {
a = i / 100; // 百位
b = (i % 100) / 10; // 十位
c = i % 10; // 个位
if (i == a*a*a + b*b*b + c*c*c) {
printf("%d\n", i);
}
}
return 0;
}
答案: 153 370 371 407
8 输出以下图案:
#include <stdio.h>
int main() {
int i, j;
// 上半部分
for (i = 1; i <= 3; i++) {
for (j = 1; j <= 2 * i - 1; j++) {
printf("*");
}
printf("\n");
}
// 下半部分
for (i = 2; i >= 1; i--) {
for (j = 1; j <= 2 * i - 1; j++) {
printf("*");
}
printf("\n");
}
return 0;
}
第六章 利用数组处理批量数据
数组是组织同类型数据的集合。
6 用筛选法求100之内的素数。
#include <stdio.h>
#include <stdbool.h> // 使用 bool 类型
#define N 100
int main() {
int i, j;
bool isPrime[N + 1]; // isPrime[0] 和 isPrime[1] 不用,从2开始
// 初始化,假设所有数都是素数
for (i = 2; i <= N; i++) {
isPrime[i] = true;
}
// 筛选
for (i = 2; i * i <= N; i++) {
if (isPrime[i]) { // 如果i是素数,则它的倍数都不是
for (j = i * i; j <= N; j += i) {
isPrime[j] = false;
}
}
}
// 输出素数
printf("100以内的素数有:\n");
for (i = 2; i <= N; i++) {
if (isPrime[i]) {
printf("%d ", i);
}
}
printf("\n");
return 0;
}
10 将一个二维数组行和列的元素互换,存到另一个二维数组中。
a[2][3] -> b[3][2]
#include <stdio.h>
#define ROWS 2
#define COLS 3
int main() {
int a[ROWS][COLS] = {{1, 2, 3}, {4, 5, 6}};
int b[COLS][ROWS];
int i, j;
printf("原数组a:\n");
for (i = 0; i < ROWS; i++) {
for (j = 0; j < COLS; j++) {
printf("%d ", a[i][j]);
b[j][i] = a[i][j]; // 关键步骤:行变列,列变行
}
printf("\n");
}
printf("\n转置后的数组b:\n");
for (i = 0; i < COLS; i++) {
for (j = 0; j < ROWS; j++) {
printf("%d ", b[i][j]);
}
printf("\n");
}
return 0;
}
答案:
原数组a:
1 2 3
4 5 6
转置后的数组b:
1 4
2 5
3 6
第七章 函数
函数是模块化编程的基础。
3 写一个判断素数的函数,在主函数输入一个整数,输出是否为素数。
#include <stdio.h>
#include <stdbool.h>
#include <math.h>
// 函数声明
bool isPrime(int num);
int main() {
int number;
printf("请输入一个正整数: ");
scanf("%d", &number);
if (number <= 1) {
printf("%d 不是素数,\n", number);
} else if (isPrime(number)) {
printf("%d 是素数,\n", number);
} else {
printf("%d 不是素数,\n", number);
}
return 0;
}
// 函数定义
bool isPrime(int num) {
if (num == 2) return true;
if (num % 2 == 0) return false;
for (int i = 3; i <= sqrt(num); i += 2) {
if (num % i == 0) {
return false;
}
}
return true;
}
8 写一个函数,使输入的一个字符串按反序存放,在主函数中输入和输出字符串。
#include <stdio.h>
#include <string.h>
// 函数声明
void reverseString(char str[]);
int main() {
char str[100];
printf("请输入一个字符串: ");
fgets(str, sizeof(str), stdin); // 使用fgets安全地读取字符串
// 去掉fgets可能读取的换行符
str[strcspn(str, "\n")] = 0;
printf("原始字符串: %s\n", str);
reverseString(str);
printf("反序后的字符串: %s\n", str);
return 0;
}
// 函数定义
void reverseString(char str[]) {
int length = strlen(str);
int i, j;
char temp;
for (i = 0, j = length - 1; i < j; i++, j--) {
temp = str[i];
str[i] = str[j];
str[j] = temp;
}
}
第八章 用户自己建立数据类型
本章介绍结构体、共用体、枚举等。
6 定义一个结构体变量(包括年、月、日),计算该日在本年中是第几天?注意闰年问题。
#include <stdio.h>
// 定义日期结构体
struct Date {
int year;
int month;
int day;
};
// 函数声明
int isLeapYear(int year);
int dayOfYear(struct Date date);
int main() {
struct Date date;
printf("请输入年、月、日(用空格隔开): ");
scanf("%d %d %d", &date.year, &date.month, &date.day);
int dayCount = dayOfYear(date);
printf "%d年%d月%d日 是该年的第 %d 天,\n", date.year, date.month, date.day, dayCount);
return 0;
}
// 判断是否是闰年
int isLeapYear(int year) {
if ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)) {
return 1;
}
return 0;
}
// 计算是一年中的第几天
int dayOfYear(struct Date date) {
int daysInMonth[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int totalDays = 0;
int i;
// 如果是闰年,2月有29天
if (isLeapYear(date.year)) {
daysInMonth[2] = 29;
}
// 累加前几个月的天数
for (i = 1; i < date.month; i++) {
totalDays += daysInMonth[i];
}
// 加上当月的天数
totalDays += date.day;
return totalDays;
}
第九章 文件
文件操作是数据持久化的关键。
6 有5个学生,每个学生有3门课的成绩,从键盘输入以上数据(包括学生号,姓名,3门课成绩),计算出平均成绩,将原有的数据和计算出的平均分数存放在磁盘文件 "stud" 中。
#include <stdio.h>
#include <string.h>
#define STUDENT_NUM 5
#define COURSE_NUM 3
// 定义学生结构体
struct Student {
char id[20];
char name[50];
float scores[COURSE_NUM];
float average;
};
int main() {
struct Student students[STUDENT_NUM];
int i, j;
FILE *fp;
// 以写入模式打开文件,如果文件不存在则创建
fp = fopen("stud.dat", "wb");
if (fp == NULL) {
printf("无法打开文件!\n");
return 1;
}
printf("请输入 %d 个学生的信息(学号 姓名 成绩1 成绩2 成绩3):\n", STUDENT_NUM);
for (i = 0; i < STUDENT_NUM; i++) {
printf("学生 %d: ", i + 1);
scanf("%s %s %f %f %f", students[i].id, students[i].name,
&students[i].scores[0], &students[i].scores[1], &students[i].scores[2]);
// 计算平均分
float sum = 0;
for (j = 0; j < COURSE_NUM; j++) {
sum += students[i].scores[j];
}
students[i].average = sum / COURSE_NUM;
// 将结构体写入文件
fwrite(&students[i], sizeof(struct Student), 1, fp);
}
fclose(fp);
printf("数据已成功保存到 stud.dat 文件中,\n");
return 0;
}
如何获取更多答案?
- 官方渠道: 谭浩强老师的官方网站或出版社有时会提供配套的习题解答。
- 在线社区:
- CSDN: 搜索 "谭浩强 C程序设计 第二版 课后答案",有大量博客和资源分享。
- GitHub: 搜索 "C-Primer-Plus-Answers" 或 "TC-C-Answers" 等关键词,可能会有一些开源的代码库。
- 知乎、博客园: 这些平台也有很多技术博主分享过该书的习题解析。
- 同学和老师: 与同学讨论或向老师请教是最好的学习方式。
再次强调: 理解解题思路远比记住答案本身重要,祝您学习顺利!
