C语言程序设计上机实验指导与习题集
前言
C语言是计算机科学的基石,其高效、灵活和接近硬件的特性使其在系统编程、嵌入式开发、游戏引擎等领域长盛不衰,学习C语言,上机实验是至关重要的环节,本指导书旨在通过一系列精心设计的实验,帮助你将理论知识转化为实际编程能力,并通过习题巩固所学,最终达到能够独立编写中等规模C语言程序的目标。

(图片来源网络,侵删)
第一部分:上机实验指导
本部分按照C语言的知识体系,设计了8个核心实验,每个实验都包含实验目的、实验环境、实验内容、实验步骤与提示。
C语言程序入门与开发环境
-
实验目的:
- 熟悉C语言程序的基本结构(
#include,main函数,注释等)。 - 掌握在集成开发环境(如Visual Studio, Dev-C++, Code::Blocks, VS Code)中编写、编译、链接和运行C语言程序的完整流程。
- 理解编译错误和链接错误的基本信息,并学会排查简单错误。
- 掌握
printf和scanf函数的基本用法,实现简单的数据输入输出。
- 熟悉C语言程序的基本结构(
-
实验环境:
- 操作系统:Windows / macOS / Linux
- IDE/编译器:Visual Studio 2025/2025, Dev-C++, Code::Blocks, 或 GCC/GDB (命令行)
-
(图片来源网络,侵删)- “Hello, World!”程序: 编写一个经典的“Hello, World!”程序,并成功运行。
- 简单计算器: 编写一个程序,提示用户输入两个整数,计算并输出它们的和、差、积、商。
- 个人信息打印: 编写一个程序,提示用户输入姓名、年龄和学号,然后按格式打印出来。
-
实验步骤与提示:
-
新建项目: 在你的IDE中创建一个新的C语言项目(Console Application)。
-
编写代码: 创建一个新的C源文件(
.c),输入以下代码并运行。#include <stdio.h> // 引入标准输入输出库 int main() { // printf函数用于向控制台输出文本 printf("Hello, World!\n"); // \n是换行符 int a, b, sum, diff, product, quotient; printf("请输入两个整数,用空格隔开: "); // scanf函数用于从键盘读取输入 // %d表示读取一个整数,&a表示将读取的值存入a的内存地址 scanf("%d %d", &a, &b); sum = a + b; diff = a - b; product = a * b; quotient = a / b; // 注意:整数除法会截断小数部分 printf("和为: %d\n", sum); printf("差为: %d\n", diff); printf("积为: %d\n", product); printf("商为: %d\n", quotient); return 0; // main函数返回0,表示程序正常结束 } -
调试与排错: 故意修改代码(如去掉分号、拼写错误、忘记
&符号),观察编译器的错误提示,并尝试修复。
(图片来源网络,侵删)
-
基本数据类型与运算符
-
实验目的:
- 掌握C语言的基本数据类型:
int,float,double,char。 - 熟悉算术运算符(, , , , )、关系运算符(
>,<, , )和逻辑运算符(&&, , )。 - 理解不同类型数据间的混合运算规则和类型转换。
- 掌握自增自减运算符(, )的前置和后置区别。
- 掌握C语言的基本数据类型:
-
- 数据类型大小: 使用
sizeof运算符输出int,float,double,char在系统中所占的字节数。 - 类型转换: 编写程序,验证整数除法和浮点数除法的区别,以及强制类型转换的效果。
- 运算符优先级: 编写一个包含多种运算符的复杂表达式,并分步计算其值,验证优先级规则。
- 数据类型大小: 使用
-
实验步骤与提示:
sizeof示例:printf("int size: %zu bytes\n", sizeof(int)); printf("float size: %zu bytes\n", sizeof(float)); // ...- 类型转换示例:
int a = 5, b = 2; float c = 5.0, d = 2.0; printf("a / b = %d\n", a / b); // 输出 2 printf("c / d = %.2f\n", c / d); // 输出 2.50 printf("(float)a / b = %.2f\n", (float)a / b); // 输出 2.50
流程控制(选择结构)
-
实验目的:
- 熟练掌握
if-else语句和switch语句的使用。 - 理解
if-else if-else的多分支结构。 - 能够运用选择结构解决实际问题,如分段函数、成绩评定等。
- 熟练掌握
-
- 分段函数: 编写程序,根据输入的x值,计算并输出y的值。
- y = x + 2 (x < 0)
- y = x² (0 ≤ x < 10)
- y = x - 2 (x ≥ 10)
- 简易计算器(升级版): 扩展实验一的计算器,增加一个菜单让用户选择要进行加、减、乘、除的运算。
- 成绩等级评定: 输入一个学生的百分制成绩,输出其对应的等级(A: 90-100, B: 80-89, C: 60-79, D: <60)。
- 分段函数: 编写程序,根据输入的x值,计算并输出y的值。
-
实验步骤与提示:
- 使用
if-else if-else实现分段函数。 - 使用
switch语句实现简易计算器的菜单选择。 - 注意
if条件的边界值(如>=和>的使用)。
- 使用
流程控制(循环结构)
-
实验目的:
- 掌握
for循环、while循环和do-while循环的使用方法和区别。 - 理解循环嵌套的概念和应用。
- 学会使用
break和continue语句控制循环流程。 - 掌握累加、累乘、计数等基本循环算法。
- 掌握
-
- 累加求和: 计算1到100之间所有整数的和。
- 阶乘计算: 计算一个非负整数n的阶乘 (n!)。
- 图形打印: 打印一个由星号(*)组成的直角三角形或金字塔。
- 猜数字游戏: 程序随机生成一个1-100的整数,用户输入猜测的数字,程序提示“猜大了”或“猜小了”,直到猜对为止。
-
实验步骤与提示:
- 累加求和和阶乘非常适合用
for或while循环。 - 打印图形需要用到循环嵌套,外层控制行数,内层控制每行的星号数量。
- 猜数字游戏需要用到
rand()和srand()函数来生成随机数,并用while(1)无限循环,配合break在猜对时退出。
- 累加求和和阶乘非常适合用
数组
-
实验目的:
- 掌握一维数组和二维数组的定义、初始化和引用。
- 学习使用循环对数组进行遍历、输入和输出。
- 掌握常用的数组算法,如查找、排序(冒泡排序)、最大/最小值等。
-
- 数组基本操作: 定义一个包含10个整数的数组,由用户输入数据,然后输出数组中的所有元素。
- 最大值与最小值: 在上述数组中找出最大值和最小值及其位置。
- 数组排序: 使用冒泡排序算法对数组进行升序排序,并输出排序后的结果。
- 二维数组应用: 定义一个3x3的二维数组,计算并输出两条对角线上的元素之和。
-
实验步骤与提示:
- 数组的下标从0开始。
- 使用
for循环遍历数组是标准做法。 - 冒泡排序的核心是双重循环,外层控制轮数,内层进行相邻元素比较和交换。
- 二维数组的对角线元素满足规律:主对角线
i == j,副对角线i + j == 2(对于3x3矩阵)。
函数
-
实验目的:
- 掌握函数的定义、声明和调用方法。
- 理解函数参数的值传递(传值)机制。
- 掌握
return语句的使用,理解函数返回值。 - 学习使用
void类型的函数。
-
- 函数封装: 将实验四中的累加求和、阶乘计算等功能封装成独立的函数。
- 素数判断: 编写一个函数
is_prime(int n),判断一个整数是否为素数,如果是返回1,否则返回0,在main函数中调用该函数,打印1-100之间的所有素数。 - 数组作为参数: 编写一个函数
print_array(int arr[], int size),用于打印一个数组,再编写一个函数find_max(int arr[], int size),用于查找数组中的最大值。
-
实验步骤与提示:
- 函数定义:
返回类型 函数名(参数列表) { 函数体 } - 函数声明(如果定义在使用之后):
返回类型 函数名(参数列表); - C语言中,数组作为参数传递时,传递的是数组首元素的地址(类似传址),可以在函数内部修改数组元素的值。
- 函数定义:
指针
-
实验目的:
- 理解指针的本质(内存地址)。
- 掌握指针变量的定义、初始化和基本运算(
&取地址,解引用/间接寻址)。 - 学习使用指针作为函数参数,实现通过函数修改主调函数中的变量(传址调用)。
- 了解指针与数组的关系。
-
- 指针基本操作: 定义一个整型变量
a和一个指向a的指针p,通过指针p修改变量a的值,并打印结果。 - 交换两个变量的值: 编写一个
swap函数,使用指针作为参数,实现交换两个整数的值。 - 指针遍历数组: 使用指针来遍历并打印一个整型数组的所有元素。
- 指针基本操作: 定义一个整型变量
-
实验步骤与提示:
int a = 10;int *p = &a;// p指向a的地址*p = 20;// 通过p间接修改a的值,此时a的值变为20swap函数原型:void swap(int *x, int *y)
结构体与文件操作
-
实验目的:
- 掌握结构体(
struct)的定义、声明和使用方法。 - 学习使用
fopen,fclose,fscanf,fprintf等标准I/O函数进行文件读写。 - 理解文本文件和二进制文件的区别。
- 能够将结构体数组中的数据写入文件,并能从文件中读出。
- 掌握结构体(
-
- 学生信息管理(文件版):
- 定义一个结构体
Student,包含学号(id)、姓名(name)、成绩(score)。 - 编写程序,可以从键盘输入多个学生的信息,并将它们保存到一个文本文件(如
students.txt)中。 - 编写另一个程序,可以从
students.txt文件中读取学生信息,并打印到屏幕上。
- 定义一个结构体
- 学生信息管理(文件版):
-
实验步骤与提示:
- 定义结构体:
struct Student { int id; char name[50]; float score; }; - 写入文件:
FILE *fp = fopen("students.txt", "w"); // "w"表示以写入模式打开文件 if (fp == NULL) { printf("Error opening file!\n"); return 1; } fprintf(fp, "%d %s %.2f\n", s.id, s.name, s.score); // 格式化写入 fclose(fp); // 关闭文件 - 读取文件:
FILE *fp = fopen("students.txt", "r"); // "r"表示以读取模式打开文件 if (fp == NULL) { printf("Error opening file!\n"); return 1; } while (fscanf(fp, "%d %s %f", &s.id, s.name, &s.score) != EOF) { // 处理读取到的数据 } fclose(fp);
- 定义结构体:
第二部分:习题集
本部分提供与实验内容对应的习题,用于巩固和拓展你的编程能力。
第一章:C语言基础
- 编写程序,将华氏温度转换为摄氏温度,公式:C = (F - 32) * 5 / 9。
- 编写程序,计算一个半径为r的圆的周长和面积。
- 编写程序,交换两个变量的值(不使用临时变量,可以使用异或运算)。
第二章:流程控制
- 编写程序,判断一个年份是否为闰年。(闰年条件:能被4整除但不能被100整除,或者能被400整除)
- 编写程序,输出100到200之间所有能被3或5整除的数。
- 编写程序,打印九九乘法表。
第三章:数组
- 在一个整型数组中,找出出现次数最多的数字。
- 将一个数组中的元素逆序存放。
- 编写程序,实现两个3x3矩阵的加法和减法。
第四章:函数
- 编写一个函数,计算一个整数的绝对值。
- 编写一个递归函数,计算斐波那契数列的第n项。
- 编写一个函数
str_len,用于计算一个字符串的长度(不能使用strlen库函数)。
第五章:指针
- 编写一个函数
str_copy,实现字符串的复制(不能使用strcpy库函数)。 - 编写一个函数
str_cmp,实现两个字符串的比较(不能使用strcmp库函数)。 - 编写一个函数,使用指针实现字符串的逆序。
第六章:综合应用
- 通讯录管理: 设计一个更完善的通讯录程序,要求:
- 使用结构体存储联系人信息(姓名、电话、邮箱)。
- 实现添加联系人、删除联系人、查找联系人、显示所有联系人、保存到文件、从文件加载等功能。
- 使用函数模块化设计,每个功能由一个函数实现。
- 学生成绩管理系统: 设计一个学生成绩管理系统,要求:
- 使用结构体存储学生信息(学号、姓名、多门课程成绩)。
- 实现录入学生成绩、计算每个学生的平均分和总分、计算每门课程的平均分、按总分排序、查询学生信息等功能。
第三部分:上机实验技巧与常见问题
- 多使用调试器: 不要只靠
printf打印信息,学会使用IDE自带的调试器,设置断点、单步执行、查看变量值,这能让你更直观地理解程序执行流程。 - 代码风格: 从一开始就养成良好的代码风格,如适当的缩进、清晰的注释、有意义的变量名,这能极大提高代码的可读性和可维护性。
- 分模块测试: 在编写复杂程序时,先确保每个小功能模块都能独立正确工作,然后再将它们组合起来。
- 善用搜索引擎和文档: 遇到问题时,先尝试自己解决,如果无法解决,可以搜索错误信息或查阅C语言标准库文档(如Cplusplus.com)。
- 常见错误:
- 语法错误: 最常见的是缺少分号、括号不匹配、拼写错误,编译器通常会给出明确的行号和提示。
- 逻辑错误: 程序能编译运行,但结果不正确,这是最难排查的,需要仔细分析算法和流程,或使用调试器。
- 内存错误: 如数组越界、空指针解引用等,这类错误可能导致程序崩溃或不可预测的行为,要格外小心。
希望这份详细的指导与习题集能对你的C语言学习之路有所帮助,祝你编程愉快!
