c 语言程序设计实验指导郑莉

99ANYc3cd6
预计阅读时长 31 分钟
位置: 首页 C语言 正文

虽然我无法直接提供一本“郑莉《C语言程序设计》实验指导书”的完整扫描版或PDF(这涉及版权问题),但我可以为您构建一个高度符合其教学风格和知识体系、循序渐进的实验指导框架,这个框架可以作为您完成实验的“路线图”和“备忘录”,涵盖了从入门到核心知识点的几乎所有关键实验。

c 语言程序设计实验指导郑莉
(图片来源网络,侵删)

郑莉《C语言程序设计》实验指导框架

本实验指导按照教材的章节顺序,分为多个实验模块,每个模块包含实验目的、实验内容、实验指导与提示、以及思考与拓展


C语言程序设计初步

实验目的:

  1. 熟悉C语言程序的开发环境(如Visual Studio, Dev-C++, Code::Blocks, VS Code等)。
  2. 掌握C语言程序的基本结构,包括头文件、主函数、注释等。
  3. 学习简单的输入/输出函数 printfscanf 的使用。
  4. 理解编译、链接、运行的基本概念。 **
  5. 经典入门: 编写一个程序,在屏幕上输出 "Hello, World!"。
  6. 简单计算器: 编写一个程序,提示用户输入两个整数,然后计算并输出它们的和、差、积、商。
  7. 个人信息打印: 编写一个程序,使用 scanf 接收用户输入的姓名、年龄和身高,然后使用 printf 将这些信息格式化地打印出来。

实验指导与提示:

  • 环境搭建: 选择一个你熟悉的IDE并完成安装,确保可以成功创建、编译、运行一个C源文件(.c)。

    c 语言程序设计实验指导郑莉
    (图片来源网络,侵删)
  • 程序结构: 一个最简单的C程序结构是:

    #include <stdio.h> // 包含标准输入输出库
    int main() {       // 主函数,程序的入口
        // 在这里写你的代码
        printf("Hello, World!\n");
        return 0;     // 返回0,表示程序正常结束
    }
  • printfscanf

    • printf 用于格式化输出。%d 用于整数,%f 用于浮点数,%c 用于字符,%s 用于字符串,\n 是换行符。
    • scanf 用于格式化输入。注意: scanf 的变量名前必须加上取地址符 &scanf("%d", &a);
  • 常见错误:

    • 忘记写 #include <stdio.h>
    • main 函数拼写错误或返回值类型错误。
    • printfscanf 中的格式控制符与变量类型不匹配(用 %d 读取一个浮点数)。
    • 忘记在 scanf 的变量名前加 &

思考与拓展:

c 语言程序设计实验指导郑莉
(图片来源网络,侵删)
  • 如何让程序输出一个浮点数,并保留两位小数?(提示:printf("%.2f", num);
  • 如果输入一个字符,应该用什么格式控制符?
  • 如果用户输入的不是数字,scanf 会发生什么?如何处理这种情况?

数据类型、运算符与表达式

实验目的:

  1. 掌握C语言的基本数据类型(int, float, double, char)及其特点。
  2. 熟悉算术运算符、赋值运算符、关系运算符和逻辑运算符的优先级和结合性。
  3. 学习使用强制类型转换。
  4. 理解自增()和自减()运算符的使用。 **
  5. 数据类型大小: 编写程序,使用 sizeof 运算符输出 int, float, double, char 在你使用的编译器中所占的字节数。
  6. 混合运算与类型转换: 定义一个 int 型变量 a 和一个 double 型变量 b,计算 a / bb / a 的值,并观察结果类型的变化,尝试使用强制类型转换 (double)a 并观察结果。
  7. 逻辑判断: 编写程序,判断一个输入的年份是否为闰年,闰年的条件是:能被4整除但不能被100整除,或者能被400整除。
  8. 复杂表达式:int a=3, b=4, c=5;,计算表达式 a + b > c && b == c 的值。

实验指导与提示:

  • sizeof sizeof 是一个运算符,不是函数。sizeof(int)sizeof(a)
  • 类型转换: 当参与运算的类型不一致时,C会进行隐式类型转换(也叫“算术转换”),除法运算中,如果两个操作数都是整数,结果也是整数(小数部分被舍弃),强制类型转换 (type)expr 可以将 expr 的结果临时转换为 type 类型。
  • 运算符优先级: , > , , > , > 关系运算符 > 逻辑与(&&) > 逻辑或(||) > 赋值运算符,可以使用括号 来明确运算顺序,这是个好习惯。
  • 闰年判断: 这是 && (与), (或), (非), (取模) 运算符的经典应用案例。

思考与拓展:

  • i++++i 在单独使用时效果一样,但在表达式中(如 a = i++a = ++i)有什么区别?
  • 如何判断一个字符是数字('0'-'9')还是字母('a'-'z', 'A'-'Z')?(提示:利用字符的ASCII码值和关系运算符)

逻辑控制语句

实验目的:

  1. 熟练掌握 if-else 语句及其嵌套,实现多分支选择结构。
  2. 掌握 switch 语句的使用,理解其与 if-else 的区别。
  3. 掌握 for, while, do-while 三种循环语句,并能用它们解决重复性问题。
  4. 学习 breakcontinue 语句在循环中的作用。 **
  5. 分段函数: 编写程序,根据输入的 x 值,计算并输出 y 的值。
    • y = x (x < 1)
    • y = 2x - 1 (1 ≤ x < 10)
    • y = 3x - 11 (x ≥ 10)
  6. 简单菜单系统: 使用 switch 语句实现一个简单的计算器菜单,用户可以选择进行加、减、乘、除或退出运算。
  7. 循环求和:
    • 计算 1 到 100 的累加和。
    • 计算 1 到 100 之间所有偶数的和。
  8. 循环嵌套: 打印九九乘法表。
  9. 素数判断: 输入一个正整数,判断它是否为素数(质数),素数是指只能被1和它本身整除的大于1的自然数。

实验指导与提示:

  • if-else 适用于范围判断,注意 else 总是和它最近的、未配对的 if 配对。
  • switch 适用于等值判断。switch 后面的表达式必须是整型(或字符型),case 后的值必须是常量。break 语句用于跳出 switch 结构,不要忘记写 break,否则会发生“case穿透”。
  • for vs while vs do-while
    • for 循环:次数确定时首选。
    • while 循环:条件控制,循环次数不确定时常用。
    • do-while 循环:至少执行一次
  • 循环嵌套: 外层循环控制行,内层循环控制列,九九乘法表是理解嵌套循环的经典案例。
  • 素数判断: 最直观的方法是,从 i=2 开始到 sqrt(n)(或 n/2),检查 n 是否能被 i 整除,如果能,则 n 不是素数。

思考与拓展:

  • 如何用 do-while 循环改写素数判断程序?
  • 在打印九九乘法表时,如何只打印下三角或上三角?
  • breakcontinue 有什么区别?break 会跳出整个循环,而 continue 只会结束本次循环,进入下一次循环。

数组

实验目的:

  1. 掌握一维数组的定义、初始化和引用方法。
  2. 学习使用数组进行批量数据处理,如排序、查找、统计等。
  3. 掌握字符串的表示方法(字符数组)和常用字符串处理函数(strlen, strcpy, strcmp 等)。
  4. 了解二维数组的基本概念和使用。 **
  5. 数组基本操作: 定义一个包含10个整数的数组,用循环为其赋值(如1到10),然后逆序输出数组中的所有元素。
  6. 排序算法: 实现一个简单的排序算法(如冒泡排序选择排序)对一个包含10个随机整数的数组进行升序排序,并输出排序前后的数组。
  7. 查找与统计:
    • 在一个已排序的数组中,使用二分查找法查找一个指定的数字,并输出其位置或“未找到”的提示。
    • 统计一个字符串中英文字母、数字、空格和其他字符的个数。
  8. 二维数组: 使用二维数组实现一个3x3的矩阵,并计算其主对角线元素之和。

实验指导与提示:

  • 数组定义: int arr[10];,C语言中,数组下标从0开始。
  • 冒泡排序: 核心思想是相邻元素比较,如果顺序错误就交换,通过多轮遍历,将最大的元素“冒泡”到数组末尾。
  • 字符串处理函数: 使用这些函数需要包含头文件 <string.h>
    • strlen(s):求字符串 s 的长度(不包括结尾的 \0)。
    • strcpy(dest, src):将字符串 src 复制到 dest
    • strcmp(s1, s2):比较两个字符串,s1 > s2 返回正数,s1 == s2 返回0,s1 < s2 返回负数。
  • 二维数组: int matrix[3][3];,访问元素使用 matrix[i][j],主对角线元素是 matrix[0][0], matrix[1][1], matrix[2][2]

思考与拓展:

  • 如何将一个字符串反转?(提示:可以交换首尾字符)
  • 除了冒泡排序,你还知道哪些排序算法?(如插入排序、选择排序)
  • 为什么 strcpy 函数不安全?有没有更安全的替代函数?(如 strncpy

函数

实验目的:

  1. 掌握函数的定义、声明和调用方法。
  2. 理解函数参数传递(值传递)的机制。
  3. 学习使用 return 语句从函数返回值。
  4. 掌握递归函数的设计思想和应用场景。 **
  5. 模块化计算器: 将实验三中的计算器功能用函数实现,编写 add(), subtract(), multiply(), divide() 四个函数,main 函数通过调用这些函数来完成计算。
  6. 素数判断函数: 将实验四中的素数判断逻辑封装成一个函数 int isPrime(int num);,该函数返回1(是素数)或0(不是素数),在 main 函数中调用它来测试多个数字。
  7. 递归应用:
    • 使用递归函数计算一个非负整数 n 的阶乘 n!
    • 使用递归函数计算斐波那契数列的第 n 项。(斐波那契数列:1, 1, 2, 3, 5, 8, ...,即 F(n) = F(n-1) + F(n-2)

实验指导与提示:

  • 函数三要素: 返回值类型、函数名、参数列表。
  • 函数声明 vs 定义: 如果函数定义在 main 函数之后,需要在 main 之前进行声明,告诉编译器这个函数的存在。int isPrime(int num);
  • 值传递: C语言中,函数参数传递是值传递,这意味着函数内部操作的是实参的副本,修改副本不会影响外部的实参。数组作为参数是个例外(传递的是数组首地址)。
  • 递归:
    • 递归出口(基准情形): 必须有一个或多个不需要再次递归调用就能直接返回结果的情形,否则会无限递归导致栈溢出。
    • 递归规则(递归情形): 函数调用自身,但参数必须向基准情形逼近。
    • 递归与栈: 每次递归调用都会在栈上分配一个新的栈帧,递归过深可能导致栈溢出。

思考与拓展:

  • 为什么传递数组不需要加 &?(因为数组名 arr 会“退化”为其首元素的地址)
  • 如何通过指针实现地址传递,从而在被调用函数中修改外部变量的值?(这是后续指针实验的内容)
  • 递归和循环(迭代)有什么优缺点?递归代码更简洁易读,但通常效率较低且可能栈溢出。

指针

实验目的:

  1. 掌握指针变量的定义、初始化和基本使用。
  2. 理解指针与数组的关系,能用指针遍历数组。
  3. 学习使用指针作为函数参数,实现地址传递。
  4. 了解指针数组与指向指针的指针(进阶内容)。 **
  5. 指针基本操作: 定义一个整型变量 a 和一个指向 a 的指针 p,通过指针 p 修改 a 的值,并分别通过 ap 输出 a 的值和地址。
  6. 指针与数组: 定义一个整型数组,使用指针(而不是下标)来遍历并打印数组中的所有元素。
  7. 指针作为函数参数:
    • 编写一个函数 void swap(int *x, int *y);,用于交换两个整数的值,在 main 函数中调用它,验证交换是否成功。
    • 编写一个函数 void bubble_sort(int arr[], int n);,使用指针(数组)参数对数组进行排序。
  8. 动态内存分配(进阶): 使用 malloc 函数在堆上动态分配一个大小为10的整型数组,用指针指向它,进行一些操作后,使用 free 函数释放内存。

实验指导与提示:

  • 指针定义: int *p;。 是指针运算符,& 是取地址运算符。p = &a; 表示 p 存储 a 的地址。
  • 指针解引用: *p 表示访问 p 所指向地址的值,通过 *p = 100; 可以修改 a 的值。
  • 指针与数组: 在C语言中,数组名 arr&arr[0] 几乎可以互换。arr[i] 等价于 *(arr + i)
  • swap 函数: 这是理解指针作为函数参数最经典的例子,因为没有值传递的限制,函数可以直接修改外部变量的内存。
  • mallocfree 使用 malloc 需要包含头文件 <stdlib.h>int *p = (int*)malloc(10 * sizeof(int));动态分配的内存在使用完毕后必须手动 free(p),否则会造成内存泄漏。

思考与拓展:

  • int *p;int *p = NULL; 有什么区别?为什么后者更好?
  • char *str = "hello";char str[] = "hello"; 有什么根本区别?(前者指向一个只读字符串字面量,后者是一个可修改的字符数组)
  • 函数指针是什么?它有什么用?(函数指针可以指向一个函数,作为参数传递或作为返回值,是实现回调等高级功能的基础)

结构体与共用体

实验目的:

  1. 掌握结构体(struct)类型的定义和使用。
  2. 学习结构体变量的初始化、成员访问。
  3. 理解结构体数组的概念。
  4. 了解结构体指针的使用。 **
  5. 学生信息管理:
    • 定义一个结构体 Student,包含成员:学号(int id)、姓名(char name[20])、成绩(float score)。
    • 定义一个 Student 类型的变量,并对其进行初始化和成员访问。
    • 定义一个 Student 类型的数组,用于存储5个学生的信息,并编写一个函数 void printStudents(Student s[], int n); 来打印所有学生的信息。
  6. 结构体指针: 修改上题,使用 Student 类型的指针来遍历和打印结构体数组中的学生信息。

实验指导与提示:

  • 结构体定义:
    struct Student {
        int id;
        char name[20];
        float score;
    };
  • 定义变量: struct Student s1;struct Student s1 = {1001, "Zhang San", 95.5};
  • 成员访问: 使用点运算符 。s1.id = 1001;printf("%s", s1.name);
  • 结构体指针: 定义 struct Student *p = &s1;,通过指针访问成员使用箭头运算符 ->p->id 等价于 (*p).id

思考与拓展:

  • 结构体的大小为什么不一定是其所有成员大小之和?(内存对齐)
  • 共用体(union)和结构体有什么区别?共用体的所有成员共享同一块内存空间。

文件操作

实验目的:

  1. 掌握文件指针(FILE *)的概念。
  2. 学习文件的打开、关闭、读写等基本操作。
  3. 熟悉常用的文件读写函数(fopen, fclose, fgetc, fputc, fgets, fputs, fscanf, fprintf)。
  4. 学习使用二进制方式读写文件。 **
  5. 文本文件写入与读取:
    • 编写程序,将实验七中5个学生的信息(格式化文本)写入到一个名为 students.txt 的文件中。
    • 编写另一个程序,从 students.txt 文件中读取学生信息,并打印到屏幕上。
  6. 命令行参数: 编写一个程序,它接受两个命令行参数:第一个是源文件名,第二个是目标文件名,程序将源文件的内容复制到目标文件中。
  7. 二进制文件(进阶): 将一个结构体数组以二进制形式写入文件,然后再从文件中读出,验证数据是否一致。

实验指导与提示:

  • 文件指针: 所有文件操作都通过 FILE * 类型的指针来完成。
  • fopen FILE *fp = fopen("filename.txt", "r");,第二个参数是打开模式:
    • "r":只读,文件必须存在。
    • "w":只写,文件不存在则创建,存在则清空。
    • "a":追加,文件不存在则创建,存在则在末尾写入。
    • "r+", "w+", "a+":读写模式。
  • 错误检查: 每次调用 fopen 后,都应该检查返回值是否为 NULL,以判断文件是否成功打开。
  • 读写函数:
    • fprintf(fp, "%d %s", id, name); // 格式化写入
    • fscanf(fp, "%d %s", &id, name); // 格式化读取
    • fputs("Hello", fp); // 写入一个字符串
    • fgets(buffer, 100, fp); // 读取一行
  • fclose 使用完文件后,必须调用 fclose(fp); 来关闭文件并释放资源。

思考与拓展:

  • 文本模式和二进制模式有什么区别?在什么情况下必须使用二进制模式?
  • 如何定位文件中的读写位置?(使用 fseek 函数)
  • 如何获取文件的大小?

综合项目设计

实验目的:

  1. 综合运用前面所学的C语言知识。
  2. 学习设计一个结构完整、功能清晰的程序。
  3. 培养分析问题、设计算法、编写代码和调试程序的综合能力。 三选一或自定):**

学生成绩管理系统

  • 功能要求:
    1. 从文件中加载学生信息(学号、姓名、多门课程成绩)。
    2. 添加、删除、修改学生信息。
    3. 按学号或姓名查找学生。
    4. 计算每个学生的总分和平均分,并可以按总分排序。
    5. 将修改后的学生信息保存回文件。
  • 涉及知识点: 结构体、数组、文件操作、指针、排序算法、循环、分支。

简易图书管理系统

  • 功能要求:
    1. 管理图书信息(书号、书名、作者、库存数量)。
    2. 添加、删除、修改图书信息。
    3. 按书名或作者查找图书。
    4. 模拟借书和还书功能(减少/增加库存)。
    5. 可以查看所有图书的列表。
  • 涉及知识点: 结构体、数组、文件操作、字符串处理、菜单界面设计。

贪吃蛇游戏

  • 功能要求:
    1. 使用控制台字符界面实现。
    2. 蛇可以由方向键控制移动。
    3. 随机生成食物,蛇吃到食物后身体变长,得分增加。
    4. 撞到墙壁或自己的身体则游戏结束。
  • 涉及知识点: (可能需要平台相关的库,如Windows的 conio.h 或Linux的 ncurses)数组(表示地图和蛇身)、循环(游戏主循环)、键盘输入、随机数生成、延时。

实验指导与提示:

  • 模块化设计: 将不同功能封装成独立的函数。addStudent(), deleteStudent(), saveToFile() 等。
  • 数据结构选择: 使用结构体数组来存储学生或图书信息,如果数据量可能很大,可以考虑使用链表(这是数据结构课程的内容,但用数组实现项目已足够)。
  • 用户界面: 设计一个清晰的菜单循环,让用户可以选择不同的功能。
  • 调试: 学会使用 printf 在关键位置打印变量值,来追踪程序的执行流程和数据变化,这是程序员最重要的技能之一。

希望这份详细的实验指导框架能对您学习郑莉老师的《C语言程序设计》有所帮助!祝您实验顺利!

-- 展开阅读全文 --
头像
织梦手机站图片如何一行排列?
« 上一篇 01-07
dede field.reid
下一篇 » 01-07

相关文章

取消
微信二维码
支付宝二维码

目录[+]