C程序设计习题集
第一章:C语言概述与程序设计基础
本章目标: 理解C语言的特点、程序的基本结构,掌握基本数据类型、常量、变量、运算符和表达式。

选择题
-
一个C语言程序的基本组成单位是( )。 A. 函数 B. 语句 C. 字符 D. 标识符
-
以下不合法的C语言标识符是( )。 A.
_totalB.student_nameC.2nd_scoreD.sum -
以下选项中,正确的整型常量是( )。 A.
1,000B.010(八进制) C.0x1G(十六进制,G非法) D.'123'(字符)
(图片来源网络,侵删) -
设有定义
int a = 3, b = 4;,则表达式a++ * --b的值是( )。 A. 12 B. 11 C. 10 D. 9 -
表达式
10 % 3的值是( )。 A. 1 B. 3 C. 0 D. 0.333...
填空题
- C语言程序总是从
______函数开始执行。 - 在C语言中,用于定义单字符的变量类型是
______。 - 定义一个双精度浮点型变量
pi并赋值为3.14,完整的语句是______。 - 若
x是一个整型变量,执行x = 5; x += 2;后,x的值是______。 - 要输出一个换行符,应使用的转义字符是
______。
判断题
main函数可以放在C程序文件的任何位置。( )- 在C语言中,变量必须先定义后使用。( )
float a = 3.14;和double a = 3.14;在内存中占用的字节数是相同的。( )a = b = c = 10;是一个合法的赋值语句。( )- 自增运算符 只能用于变量,不能用于常量或表达式。( )
简答题
- 简述C语言程序的基本结构。
- 什么是变量?什么是常量?请各举一例。
- 简述
printf和scanf函数的作用。 - 什么是“类型转换”?C语言中有哪些类型转换方式?
编程题
- Hello, World!:编写一个程序,在屏幕上输出 "Hello, World!"。
- 变量交换:定义两个整型变量
a和b,分别赋值为10和20,然后交换它们的值并输出交换后的结果。 - 计算圆的面积和周长:从键盘输入一个圆的半径,计算并输出其面积和周长(保留两位小数)。(提示:π可以使用
14159) - 算术运算:定义三个整型变量
a,b,c,并分别为其赋值,计算并输出a+b,a-b,a*b,a/b,a%b的结果。
第二章:顺序、选择与循环结构
本章目标: 掌握三种基本程序结构(顺序、选择、循环)的实现方法,熟练使用 if-else、switch、for、while、do-while 等语句。
选择题
-
以下
if语句语法正确的是( )。 A.if (x > 0) printf("Positive");B.if x > 0 then printf("Positive");C.if (x > 0) { printf("Positive"); }D.if (x > 0) { printf("Positive"); } else { printf("Negative"); }(这个语法正确,但C是if...else) -
for (i = 0; i < 10; i++) { ... }循环执行的次数是( )。 A. 9次 B. 10次 C. 11次 D. 0次 -
以下关于
switch语句的描述,错误的是( )。 A.switch后面的表达式必须是整型或字符型 B.case后面的常量表达式必须互不相同 C. 如果没有break语句,程序会执行下一个caseD.default分支是必须的 -
while循环和do-while循环的主要区别是( )。 A.while循环更高效 B.do-while循环至少执行一次 C.while循环的条件判断在前 D. B和C -
要实现“当
i从1到100,且i能被7整除时,打印i”的功能,最适合的循环语句是( )。 A.if语句 B.for循环 C.while循环 D.switch语句
填空题
- 在
if (a > b) c = a; else c = b;中,c的值将是a和b中的较大者,这可以用一个三元运算符表示为c = ______。 - 循环结构中,用于立即跳出本层循环的关键字是
______。 - 循环结构中,用于结束本次循环,直接进入下一次循环的关键字是
______。 - 以下代码的输出结果是
______。int i = 0; while (i < 5) { printf("%d ", i); i++; } switch语句中,______关键字用于终止switch结构的执行。
编程题
- 判断奇偶数:从键盘输入一个整数,判断它是奇数还是偶数,并输出相应信息。
- 成绩等级评定:从键盘输入一个学生的百分制成绩,要求输出其对应的等级,规则如下:
- 90分以上:A
- 80-89:B
- 70-79:C
- 60-69:D
- 60分以下:E
- 求1到100的和:使用循环结构计算1到100所有整数的和。
- 猜数字游戏(简化版):程序预先设定一个1到10之间的整数(
secret = 7),然后让用户输入一个数字进行猜测,如果猜对了,输出“恭喜你,猜对了!”;如果猜错了,输出“猜错了,再试试!”。 - 水仙花数:找出所有三位数中的“水仙花数”,水仙花数是指一个三位数,其各位数字立方和等于它本身,153 = 1³ + 5³ + 3³。
第三章:数组
本章目标: 理解数组的概念,掌握一维数组和二维数组的定义、初始化、引用和基本操作(如排序、查找)。
选择题
-
在C语言中,定义一个有10个整型元素的数组,正确的语句是( )。 A.
int a[10];B.int a(10);C.int a = {0,1,2,3,4,5,6,7,8,9};D.int a[10] = {0};(这个也正确,但A是基本定义) -
数组
int arr[5] = {1, 2, 3};中,arr[3]的值是( )。 A. 3 B. 4 C. 0 D. 未定义 -
以下关于字符串的描述,错误的是( )。 A. C语言中没有专门的字符串类型,通常用字符数组表示 B. 字符串的结束标志是
'\0'C.char str[] = "Hello";定义了一个长度为5的字符串 D.sizeof("Hello")的值通常是6(包括'\0') -
二维数组
int a[3][4];共有( )个元素。 A. 3 B. 4 C. 7 D. 12 -
要对数组进行升序排序,以下哪种算法最常用且效率较高(在平均情况下)? A. 冒泡排序 B. 选择排序 C. 快速排序 D. 插入排序
填空题
- C语言中,数组的下标是从
______开始的。 - 要遍历一个长度为
n的数组,循环变量的范围通常是0到______。 - 使用
scanf函数向字符数组str中输入一个字符串,语句应为______。 - 定义一个二维数组
int matrix[2][3] = {{1,2,3}, {4,5,6}};,则matrix[1][2]的值是______。 - 将数组
arr中的所有元素逆序存放,可以使用两个下标,一个从0开始,一个从______开始,然后交换它们指向的元素。
编程题
-
数组元素求和与平均值:定义一个包含10个整数的数组,计算并输出所有元素的总和及平均值。
-
查找数组中的最大值和最小值:从键盘输入5个整数存入数组,找出其中的最大值和最小值。
-
数组元素逆序:将一个数组中的元素逆序存放,并输出逆序前后的数组。
-
冒泡排序:使用冒泡排序算法对给定的整数数组(
{64, 34, 25, 12, 22, 11, 90})进行升序排序,并输出排序后的结果。 -
矩阵转置:定义一个2x3的矩阵,并将其转置为3x2的矩阵后输出。
原矩阵: 1 2 3 4 5 6 转置后: 1 4 2 5 3 6
第四章:函数
本章目标: 掌握函数的定义、声明、调用,理解参数传递(值传递),了解变量的作用域和存储类别,理解递归的基本思想。
选择题
-
C语言程序由函数组成,以下说法正确的是( )。 A. 一个C程序可以包含多个主函数
mainB. 函数的定义可以嵌套,但函数的调用不能嵌套 C. 一个C程序有且仅有一个main函数 D.main函数必须放在程序的开头 -
在C语言中,函数参数传递的方式是( )。 A. 地址传递 B. 引用传递 C. 值传递 D. 指针传递 (指针传递本质上还是值传递,传递的是地址值)
-
以下关于函数返回值的描述,正确的是( )。 A. 函数可以返回多个值 B. 函数可以返回任何类型的值 C.
void类型的函数不能有return语句 D. 函数返回值的类型由return语句后的表达式决定 -
在函数内部定义的变量,其作用域是( )。 A. 从定义处到整个文件末尾 B. 从定义处到函数末尾 C. 整个程序 D. 从定义处到下一个
-
递归函数必须包含( )。 A.
for循环 B.while循环 C. 至少一个return语句 D. 能够终止递归的条件判断
填空题
- 函数定义由函数头和函数体组成,函数头包括返回类型、函数名和
______。 - 在函数调用前,如果函数定义在
main函数之后,通常需要在main函数前进行______。 - 在C语言中,使用
______关键字来表示一个函数没有返回值。 - 递归解决问题的两个关键要素是
______和______。 - 以下程序的输出结果是
______。int add(int a, int b) { return a + b; } int main() { int result = add(5, add(2, 3)); printf("%d", result); return 0; }
编程题
- 求阶乘(非递归):编写一个函数
int factorial(int n),使用循环计算一个非负整数n的阶乘,并在main函数中调用它。 - 判断素数:编写一个函数
int is_prime(int num),判断一个整数num是否为素数(质数),如果是返回1,否则返回0,在main函数中测试该函数。 - 数组排序函数:将上一章的冒泡排序算法封装成一个函数
void bubble_sort(int arr[], int n),该函数接收一个整型数组和它的长度,并对数组进行排序,在main函数中调用它。 - 递归求斐波那契数列:斐波那契数列定义如下:F(0)=0, F(1)=1, F(n)=F(n-1)+F(n-2) (n>=2),编写一个递归函数
int fibonacci(int n)来计算第n个斐波那契数。 - 多个值的返回:编写一个函数
void find_min_max(int arr[], int n, int *min, int *max),该函数能在一个数组中找到最小值和最大值,并通过指针参数返回给调用者,在main函数中测试。
第五章:指针
本章目标: 深刻理解指针的概念,掌握指针的定义、初始化、指针运算,理解指针与数组、函数的关系,学会使用指针作为函数参数和返回值。
选择题
-
变量的“地址”是( )。 A. 变量名 B. 变量的值 C. 变量在内存中的存储位置 D. 变量的类型
-
已有
int a = 10; int *p = &a;,则以下表达式值为10的是( )。 A.aB.*aC.pD.&p -
int *p[10];的描述,正确的是( )。 A.p是一个指向整型变量的指针 B.p是一个包含10个整型元素的数组 C.p是一个包含10个指向整型变量的指针的数组 D. 语法错误 -
函数参数传递中,使用指针传递可以实现( )。 A. 提高传递效率(传递地址比传大数据快) B. 在函数内部修改主调函数变量的值 C. A和B D. 只能传递字符串
-
char *str = "Hello";和char str[] = "Hello";的主要区别是( )。 A. 没有区别 B. 第一个定义的str是一个常量字符串,不能修改其内容 C. 第二个定义的str是一个常量字符串 D. 第一个定义的str占用更多内存
填空题
- 专门用于存储内存地址的变量类型称为
______。 - “取地址”运算符是
______,“间接访问”(或“解引用”)运算符是______。 - 如果指针
p指向数组arr的第一个元素,则p+1指向______。 - 函数指针是一个指向
______的指针。 void *类型的指针被称为______指针,它可以指向任何类型的数据,但在使用前通常需要强制转换。
编程题
- 指针变量交换两个数:使用指针作为函数参数,编写一个函数
void swap(int *a, int *b),交换两个整数的值,在main函数中调用并验证。 - 指针遍历数组:定义一个整型数组,使用指针(而不是数组下标)来遍历并打印数组中的所有元素。
- 字符串长度:不使用
strlen库函数,自己编写一个函数int my_strlen(const char *str),使用指针计算字符串的长度。 - 使用指针实现冒泡排序:修改第四章的冒泡排序函数,使其完全使用指针操作来比较和交换数组元素。
- 指针数组:定义一个指针数组,其中每个元素都指向一个字符串(
char *books[] = {"C Primer", "The C Programming Language", ...}),然后打印出所有书名。
第六章:结构体与共用体
本章目标: 掌握结构体(struct)的定义和使用,理解结构体数组、结构体指针,了解共用体(union)的概念和特点。
选择题
-
定义一个表示“学生”的结构体,包含
name(字符串) 和score(浮点数),以下定义正确的是( )。 A.struct student { char name[20]; float score; };B.struct student { char name; float score; };C.student { char name[20]; float score; };D.struct { char name[20]; float score; } student;(这个也正确,但A是更常见的结构体类型定义) -
已定义结构体
struct Point { int x; int y; };和结构体变量struct Point p1;,要给p1的x成员赋值10,正确的语句是( )。 A.p1.x = 10;B.p1 -> x = 10;C.*p1.x = 10;D.p1 = {10, 0};(C99标准支持) -
结构体变量占用内存的大小是( )。 A. 其所有成员占用内存的总和 B. 其占用内存最大的成员的大小 C. 所有成员占用内存总和加上可能的填充字节 D. 固定为4个字节
-
共用体(
union)的特点是( )。 A. 所有成员同时被存储 B. 所有成员共享同一段内存空间 C. 可以同时初始化所有成员 D. 大小是其最大成员的大小 -
通过结构体指针访问其成员,使用的运算符是( )。 A. B.
&C. D.->
填空题
- 定义结构体类型的关键字是
______。 struct Date { int year; int month; int day; } d1;中,d1是一个______变量。struct Book *ptr;定义了一个指向______类型的指针。- 共用体的关键字是
______。 - 使用
sizeof运算符可以测出一个结构体变量占用的字节数,这有助于理解内存对齐。
编程题
- 学生信息结构体:定义一个学生结构体,包含学号(
int id)、姓名(char name[20])和成绩(float score),在main函数中定义一个该结构体的变量,并为它的成员赋值,然后打印出来。 - 结构体数组:定义一个包含3个学生信息的结构体数组,并遍历数组,打印所有学生的信息。
- 结构体指针:使用结构体指针来访问和修改第1题中创建的学生结构体的成员。
- 共用体大小计算:定义一个共用体
union Data { int i; float f; char c; };,使用sizeof运算符输出该共用体的大小,并解释原因。 - 简单的链表节点:定义一个表示链表节点的结构体
struct Node { int data; struct Node *next; };,在main函数中手动创建两个节点,并将它们链接起来(即让第一个节点的next指针指向第二个节点),然后打印第二个节点的数据。
第七章:文件操作
本章目标: 掌握文件的基本概念,学会使用 fopen, fclose, fgetc, fputc, fgets, fputs, fscanf, fprintf, fread, fwrite 等函数进行文件的读写操作。
选择题
-
在C语言中,对文件进行操作的一般步骤是( )。 A. 打开文件 -> 读写文件 -> 关闭文件 B. 定义文件指针 -> 读写文件 -> 关闭文件 C. 读写文件 -> 关闭文件 D. 打开文件 -> 关闭文件
-
FILE *fp;中的fp是一个( )。 A. 文件名 B. 文件结构体指针 C. 文件内容 D. 文件句柄 -
fopen("test.txt", "w")的作用是( )。 A. 以只读方式打开文件 "test.txt" B. 以追加方式打开文件 "test.txt" C. 以写方式打开文件 "test.txt",如果文件不存在则创建,如果存在则清空 D. 以读写方式打开文件 "test.txt" -
当文件读写操作出错时,
fgetc函数会返回( )。 A.EOFB.0C. 文件指针 D. 第一个字符的ASCII码 -
以下函数中,用于以二进制方式读写数据块的是( )。 A.
fprintf和fscanfB.fgets和fputsC.fgetc和fputcD.fread和fwrite
填空题
fopen函数用于______文件,fclose函数用于______文件。EOF是一个在头文件stdio.h中定义的宏,通常值是______,表示文件结束或读取失败。- 要将格式化数据写入文本文件,应使用
______函数。 - 要从文本文件中读取一行字符串,应使用
______函数。 - 在程序结束前,必须关闭所有打开的文件,以防止数据丢失和资源浪费。
编程题
- 写入文本文件:编写一个程序,将 "Hello, File!" 这行字符串写入到一个名为
output.txt的文件中。 - 读取文本文件:编写一个程序,读取上一题创建的
output.txt文件,并将其内容逐字符读取并打印到屏幕上。 - 格式化读写:定义一个学生结构体(同第六章),创建3个学生信息,然后使用
fprintf将这些信息以格式化的方式写入students.txt文件,再编写一个程序,从students.txt中读取这些信息并打印。 - 二进制文件拷贝:编写一个程序,将一个文件(
a.jpg)以二进制方式读取,并原样写入到另一个文件(b.jpg)中,实现一个简单的文件拷贝功能。 - 统计文件字符数:编写一个程序,打开一个文本文件,统计其中包含的字符总数(不包括换行符等空白字符可能不算,看具体要求,这里可以算上所有字符)。
综合大题
学生成绩管理系统**
要求: 使用C语言设计一个简单的命令行学生成绩管理系统,具备以下功能:
- 数据结构:使用结构体
Student来存储学生信息,包括学号(char id[10])、姓名(char name[20])和三门课程的成绩(float score1,float score2,float score3)。 - 功能模块:
- 录入学生信息:可以从键盘输入多个学生的信息,并将信息保存到一个文件(如
students.dat)中。 - 显示所有学生信息:从文件中读取所有学生信息,并在屏幕上以表格形式显示出来。
- 计算并显示每个学生的平均分:在显示学生信息时,同时计算并显示每个学生的三门课的平均分。
- 按学号查询学生信息:输入一个学号,查找并显示该学生的详细信息。
- (可选)按平均分排序:将所有学生按平均分从高到低排序后显示或保存。
- 录入学生信息:可以从键盘输入多个学生的信息,并将信息保存到一个文件(如
- 文件操作:所有学生信息必须持久化存储在文件中,程序启动时从文件加载,退出时保存到文件。
提示:
- 需要一个主菜单,让用户选择要执行的操作。
- 使用
struct Student students[100];这样的数组来存储当前在内存中的学生数据。 - 使用
fopen的 "rb" (读二进制) 和 "wb" (写二进制) 模式来读写students.dat文件。 - 使用
fwrite和fread函数来高效地读写结构体数组。
这个综合题能很好地考察你对结构体、数组、文件操作、循环、选择结构以及函数模块化设计的综合掌握能力。
