第一部分:基础入门
题型 1:Hello World 与基本输出
** 编写一个C程序,在屏幕上打印 "Hello, World!"。

答案:
#include <stdio.h> // 包含标准输入输出库,提供 printf 函数
int main() {
// printf 函数用于格式化输出字符串
// \n 是一个转义字符,表示换行
printf("Hello, World!\n");
// main 函数的返回值 0 表示程序正常退出
return 0;
}
解析:
#include <stdio.h>:这是预处理指令,告诉编译器在编译前将stdio.h文件的内容包含进来。stdio.h是 "Standard Input/Output Header" 的缩写,它包含了像printf(格式化输出) 和scanf(格式化输入) 这样的函数声明。int main():这是程序的入口点,每个C程序都必须有一个main函数。int表示main函数执行完毕后会返回一个整数值给操作系统。printf("Hello, World!\n");:printf是 "print formatted" 的缩写,它会将括号内的字符串原样输出到控制台。\n是一个换行符,确保下一次输出会从新的一行开始。return 0;:main函数返回0通常是表示程序成功执行完毕,没有发生任何错误。
题型 2:变量、数据类型与基本运算
** 编写一个程序,声明两个整型变量 a 和 b,分别赋值为10和5,然后计算并输出它们的和、差、积、商和余数。
答案:

#include <stdio.h>
int main() {
// 1. 声明并初始化变量
int a = 10;
int b = 5;
// 2. 声明变量来存储计算结果
int sum, difference, product, quotient, remainder;
// 3. 进行计算
sum = a + b;
difference = a - b;
product = a * b;
// 注意:整数除法会截断小数部分
quotient = a / b;
// % 运算符用于求余数,只能用于整数
remainder = a % b;
// 4. 输出结果
// 使用 %d 作为整数的占位符
printf("a = %d, b = %d\n", a, b);
printf("和: %d\n", sum);
printf("差: %d\n", difference);
printf("积: %d\n", product);
printf("商: %d\n", quotient);
printf("余数: %d\n", remainder);
return 0;
}
解析:
- 变量声明与初始化:
int a = 10;声明了一个名为a的整型变量,并立即为其赋值10。 - 基本运算符:
- 加法
- 减法
- 乘法
- 除法(注意:当两个操作数都是整数时,结果也是整数,小数部分会被舍弃。
10 / 3的结果是3)。 - 取模/求余运算符(只适用于整数类型),用于获取除法后的余数。
10 % 3的结果是1。
printf的格式化输出:printf中的%d是一个格式说明符,它会用后面对应的变量(这里是a和b的值)来替换掉%d。\n用于在每次输出后换行,使结果更清晰。
第二部分:流程控制
题型 3:if-else 条件语句
** 编写一个程序,从用户输入一个整数,判断它是正数、负数还是零,并输出相应的提示信息。
答案:
#include <stdio.h>
int main() {
int number;
// 提示用户输入
printf("请输入一个整数: ");
// 从标准输入读取一个整数,并存储到 number 变量中
scanf("%d", &number);
// 使用 if-else if-else 结构进行判断
if (number > 0) {
printf("这是一个正数,\n");
} else if (number < 0) {
printf("这是一个负数,\n");
} else {
printf("这个数是零,\n");
}
return 0;
}
解析:

scanf("%d", &number);:scanf用于从标准输入(通常是键盘)读取数据。%d:表示要读取一个整数。&number:&是取地址运算符。scanf需要知道变量的内存地址,以便将读取到的值存入其中。初学者最容易忘记&。
if-else if-else结构:if (number > 0):如果条件number > 0为真,则执行其后的代码块。else if (number < 0):如果前面的if条件为假,则判断这个条件,如果为真,则执行其后的代码块。else:如果以上所有条件都为假,则执行else后的代码块,它等价于number == 0。
题型 4:for 循环
** 编写一个程序,使用 for 循环打印出从 1 到 10 的所有整数。
答案:
#include <stdio.h>
int main() {
// for 循环语法: for (初始化; 条件判断; 循环后操作)
for (int i = 1; i <= 10; i++) {
// 在每次循环中,打印 i 的值
printf("%d ", i);
}
// 打印一个换行符,使输出更美观
printf("\n");
return 0;
}
解析:
for循环三要素:- 初始化:
int i = 1;在循环开始前执行,只执行一次,这里声明并初始化了一个循环计数器i。 - 条件判断:
i <= 10;在每次循环开始前检查,如果条件为真,则执行循环体;如果为假,则循环结束。 - 循环后操作:
i++在每次循环体执行完毕后执行。i++是i = i + 1的缩写,使计数器i自增。
- 初始化:
- 循环过程:
i初始化为 1。- 检查
1 <= 10,为真,打印1。 i自增为 2。- 检查
2 <= 10,为真,打印2。 i自增为 11。- 检查
11 <= 10,为假,循环终止。
题型 5:while 循环
** 编写一个程序,实现一个简单的猜数字游戏,程序随机生成一个1到100之间的数字,然后让用户输入猜测的数字,并提示用户猜的数字是偏大、偏小还是正确,直到猜中为止。
答案:
#include <stdio.h>
#include <stdlib.h> // 用于 rand() 和 srand()
#include <time.h> // 用于 time()
int main() {
int secretNumber, guess, attempts = 0;
// 使用当前时间作为随机数生成器的种子,确保每次运行程序时随机数不同
srand(time(NULL));
// 生成 1 到 100 之间的随机数
secretNumber = rand() % 100 + 1;
printf("我已经想好了一个1到100之间的数字,请你来猜一猜!\n");
// 使用 while(1) 创建一个无限循环,直到 break 语句被执行
while (1) {
attempts++;
printf("请输入你的猜测: ");
scanf("%d", &guess);
if (guess > secretNumber) {
printf("你猜的数字太大了!\n");
} else if (guess < secretNumber) {
printf("你猜的数字太小了!\n");
} else {
printf("恭喜你!猜对了!你总共猜了 %d 次,\n", attempts);
break; // 猜对后,使用 break 退出循环
}
}
return 0;
}
解析:
while(1):这是一个无限循环,循环体内的代码会一直重复执行,直到遇到break语句。- 随机数生成:
srand(time(NULL));:srand用于初始化随机数生成器,如果不初始化,rand()每次运行程序都会产生相同的随机数序列。time(NULL)返回当前时间的秒数,作为一个变化的种子,确保每次运行程序时生成的随机数都不同。rand() % 100 + 1:rand()生成一个0到RAND_MAX(一个很大的整数)之间的随机数。% 100的结果是0到99,再加1,就得到了1到100之间的随机数。
break语句:break用于立即跳出当前的循环(这里是while循环)。
第三部分:函数
题型 6:函数的定义、声明与调用
** 编写一个程序,包含一个名为 isEven 的函数,该函数接收一个整数作为参数,如果该整数是偶数则返回 1 (真),否则返回 0 (假),在 main 函数中调用此函数,并测试几个数字。
答案:
#include <stdio.h>
// 函数声明(可选,但如果函数定义在 main 之后,则必须有)
// 告诉编译器后面会有一个 isEven 函数
int isEven(int num);
// main 函数
int main() {
int num1 = 10, num2 = 7;
// 调用 isEven 函数,并打印结果
if (isEven(num1)) {
printf("%d 是偶数,\n", num1);
} else {
printf("%d 是奇数,\n", num1);
}
if (isEven(num2)) {
printf("%d 是偶数,\n", num2);
} else {
printf("%d 是奇数,\n", num2);
}
return 0;
}
// 函数定义
int isEven(int num) {
// num 对 2 取余为 0,则是偶数
if (num % 2 == 0) {
return 1; // 返回真
} else {
return 0; // 返回假
}
// 或者更简洁的写法:
// return (num % 2 == 0);
}
解析:
- 函数声明:
int isEven(int num);告诉编译器isEven函数的存在,它接收一个int类型的参数,并返回一个int类型的值,当函数定义在main函数之后时,这是必须的。 - 函数定义:
int isEven(int num) { ... }是函数的完整实现。int num:这是参数,是一个局部变量,用于接收调用者传递过来的值。return ...;:return语句用于从函数中返回一个值,并终止函数的执行。
- 函数调用:在
main函数中,isEven(num1)就是一次函数调用,程序会跳转到isEven函数的定义处执行,执行完毕后再返回到main函数中isEven(num1)的位置,并用其返回值参与后续的if判断。
第四部分:数组与字符串
题型 7:一维数组
** 编写一个程序,声明一个包含10个整数的数组,用循环为其赋值为1到10,然后逆序打印这个数组。
答案:
#include <stdio.h>
int main() {
int numbers[10]; // 声明一个可以存放10个整数的数组
// 使用 for 循环为数组赋值
for (int i = 0; i < 10; i++) {
numbers[i] = i + 1; // 数组索引从0开始,numbers[0] 对应第一个元素
}
printf("数组逆序输出为: ");
// 使用另一个 for 循环逆序打印数组
// 从最后一个元素 (索引 9) 开始,到第一个元素 (索引 0) 结束
for (int i = 9; i >= 0; i--) {
printf("%d ", numbers[i]);
}
printf("\n");
return 0;
}
解析:
- 数组声明:
int numbers[10];声明了一个名为numbers的整型数组,它可以存储10个整数。 - 数组索引:C语言中数组的索引从 0 开始。
numbers[0]是第一个元素,numbers[9]是最后一个元素。 - 数组赋值:通过循环和索引
numbers[i]可以访问和修改数组中的每一个元素。 - 逆序遍历:第二个
for循环的初始条件是i = 9,循环条件是i >= 0,每次循环后i--,从而实现了从后向前遍历数组。
题型 8:字符串
** 编写一个程序,实现一个简单的字符串反转功能,将 "hello" 反转为 "olleh"。
答案:
#include <stdio.h>
#include <string.h> // 用于 strlen 函数
// 函数声明
void reverseString(char str[]);
int main() {
char myString[100]; // 定义一个足够大的字符数组来存储字符串
printf("请输入一个字符串: ");
// 使用 scanf 读取字符串,直到遇到空白字符(空格、Tab、回车)
scanf("%s", myString);
reverseString(myString);
printf("反转后的字符串是: %s\n", myString);
return 0;
}
// 函数定义:反转字符串
void reverseString(char str[]) {
int length = strlen(str); // 获取字符串长度
int i, j;
char temp;
// 使用双指针法进行交换
// i 从前向后,j 从后向前
for (i = 0, j = length - 1; i < j; i++, j--) {
// 交换 str[i] 和 str[j]
temp = str[i];
str[i] = str[j];
str[j] = temp;
}
}
解析:
- 字符串表示:在C语言中,字符串通常被表示为以空字符
'\0'结尾的字符数组。 #include <string.h>:C标准库中处理字符串的头文件,提供了strlen(求长度)、strcpy(拷贝)、strcmp(比较) 等常用函数。scanf("%s", myString);:注意,这里没有使用&,因为数组名myString会“退化”为其首元素的地址。strlen(str):该函数返回字符串的长度,不包括结尾的空字符'\0'。- 反转算法:
- 使用两个指针,一个
i指向字符串的开头,一个j指向字符串的末尾。 - 交换
str[i]和str[j]的值。 i向后移动一位 (i++),j向前移动一位 (j--)。- 重复此过程,直到
i不再小于j,此时字符串已经完全反转。
- 使用两个指针,一个
第五部分:指针
题型 9:指针基础
** 编写一个程序,演示指针的基本用法:声明一个整型变量,声明一个指向该变量的指针,通过指针修改变量的值,并打印修改前后的值。
答案:
#include <stdio.h>
int main() {
int var = 10; // 声明一个整型变量 var
int *ptr; // 声明一个整型指针 ptr
ptr = &var; // 将 var 的地址赋给 ptr,ptr 现在指向 var
printf("var 的值: %d\n", var);
printf("var 的地址: %p\n", (void*)&var); // %p 用于打印地址,(void*)是类型转换
printf("ptr 存储的地址: %p\n", (void*)ptr);
printf("ptr 指向的值: %d\n", *ptr); // * 是解引用/间接寻址运算符
// 通过指针修改 var 的值
*ptr = 20;
printf("\n通过指针修改 var 的值后:\n");
printf("var 的新值: %d\n", var);
printf("ptr 指向的新值: %d\n", *ptr);
return 0;
}
解析:
- 指针声明:
int *ptr;声明了一个名为ptr的指针,它指向一个整型数据。 表示这是一个指针。 - 取地址运算符
&:&var获取变量var在内存中的地址。 - 赋值:
ptr = &var;将var的地址存入指针ptr中,ptr就“指向”了var。 - *解引用运算符 ``**:
- 在声明时 (
int *ptr), 表示ptr是一个指针。 - 在使用时 (
*ptr), 表示“获取ptr所指向地址中存储的值”。 *ptr = 20;的意思是“找到ptr指向的内存位置(也就是var的位置),并将值20存入其中”,这直接修改了var的值。
- 在声明时 (
第六部分:结构体
题型 10:结构体
** 定义一个表示“学生”的结构体,包含姓名(字符串)、学号(整数)和成绩(浮点数),然后声明一个该结构体的变量,为其赋值,并打印其信息。
答案:
#include <stdio.h>
#include <string.h>
// 1. 定义学生结构体
struct Student {
char name[50];
int id;
float score;
};
// 为了方便打印,可以定义一个函数
void printStudent(struct Student s);
int main() {
// 2. 声明一个结构体变量并初始化
struct Student student1;
strcpy(student1.name, "张三"); // 字符串不能直接用 = 赋值,需要用 strcpy
student1.id = 2025001;
student1.score = 95.5;
// 3. 打印学生信息
printf("学生信息:\n");
printf("姓名: %s\n", student1.name);
printf("学号: %d\n", student1.id);
printf("成绩: %.2f\n", student1.score); // %.2f 表示保留两位小数
printf("\n--- 通过函数打印 ---\n");
printStudent(student1);
return 0;
}
// 结构体作为函数参数
void printStudent(struct Student s) {
printf("姓名: %s\n", s.name);
printf("学号: %d\n", s.id);
printf("成绩: %.2f\n", s.score);
}
解析:
- 结构体定义:
struct Student { ... };定义了一个新的数据类型Student,它像一个模板,包含了name,id,score这些不同类型的数据成员。 - 结构体变量声明:
struct Student student1;声明了一个Student类型的变量student1,系统会为student1分配足够的内存来存放其所有成员。 - 成员访问:使用点运算符 来访问结构体变量的成员。
student1.name访问name成员,student1.id访问id成员。 - 字符串赋值:对于字符数组(字符串),不能直接用 赋值,必须使用字符串拷贝函数
strcpy。
第七部分:文件操作
题型 11:文件读写
** 编写一个程序,将一段文本 "Hello, File I/O!" 写入到一个名为 output.txt 的文件中,再编写一个程序,从 output.txt 文件中读取内容并打印到屏幕上。
答案 1:写入文件 (write_file.c)
#include <stdio.h>
int main() {
FILE *fp; // 声明一个文件指针
char *text = "Hello, File I/O!\n";
// fopen 以 "写" 模式打开文件
// "w" 模式:如果文件不存在,则创建;如果文件存在,则清空其内容
fp = fopen("output.txt", "w");
// 检查文件是否成功打开
if (fp == NULL) {
printf("无法打开文件!\n");
return 1; // 返回非零值表示错误
}
// fprintf 向文件中写入格式化数据
fprintf(fp, "%s", text);
// 关闭文件,非常重要!
fclose(fp);
printf("文本已成功写入 output.txt\n");
return 0;
}
答案 2:读取文件 (read_file.c)
#include <stdio.h>
int main() {
FILE *fp; // 声明一个文件指针
char buffer[100]; // 用于存储从文件读取的内容
// fopen 以 "读" 模式打开文件
// "r" 模式:要求文件必须存在
fp = fopen("output.txt", "r");
// 检查文件是否成功打开
if (fp == NULL) {
printf("无法打开文件!\n");
return 1;
}
// fgets 从文件中读取一行字符串
// 它会读取最多 sizeof(buffer)-1 个字符,并在末尾添加 '\0'
// 当读到文件末尾或出错时,fgets 返回 NULL
if (fgets(buffer, sizeof(buffer), fp) != NULL) {
printf("从文件中读取的内容是: %s", buffer);
}
// 关闭文件
fclose(fp);
return 0;
}
解析:
- *`FILE `**:文件指针是C语言进行文件操作的核心,它指向一个包含文件信息(如文件位置、状态等)的结构体。
fopen(filename, mode):打开文件。filename:文件名。mode:打开模式。"r":只读,文件必须存在。"w":只写,如果文件不存在则创建,如果存在则清空。"a":追加,如果文件不存在则创建,如果存在则在文件末尾写入。"r+":读写,文件必须存在。"w+":读写,如果文件不存在则创建,如果存在则清空。
fprintf(fp, "...", ...):类似于printf,但是输出目标是文件指针fp指向的文件。fgets(buffer, size, fp):从文件fp中读取一行,最多读取size-1个字符,存入buffer,并在末尾自动添加'\0'。fclose(fp):关闭文件,释放相关资源,这是一个好习惯,可以防止数据丢失和文件损坏。
总结与建议
这份题库答案覆盖了C语言从入门到核心应用的大部分关键知识点,对于学习和备考,建议您:
- 亲手敲代码:不要只看不练,将每个例子都亲手输入、编译、运行,并尝试修改其中的部分,观察结果变化。
- 理解原理:重点关注每个知识点背后的原理,比如指针就是地址,数组名就是首地址,结构体是自定义数据类型等。
- 多做练习:在掌握这些例题的基础上,寻找更多相关的练习题进行巩固,可以尝试用不同方法解决同一个问题(反转字符串可以用循环,也可以用递归)。
- 调试程序:学会使用编译器的错误信息和调试工具,遇到错误时,仔细阅读错误提示,是学习过程中的重要一环。
希望这份详尽的C语言题库答案对您有帮助!祝您学习顺利!
