C语言编程基础上机指导与练习,如何高效掌握?

99ANYc3cd6
预计阅读时长 34 分钟
位置: 首页 C语言 正文
  1. 上机准备与环境搭建:教你如何开始。
  2. 核心知识点与上机指导:按知识点划分,每个知识点都包含理论、代码示例、常见错误和针对性练习。
  3. 综合项目实践:通过一个小项目将所有知识串联起来。
  4. 常见问题与调试技巧:解决你一定会遇到的问题。

第一部分:上机准备与环境搭建

在写第一行代码之前,你需要准备一个“工作台”。

C语言编程基础上机指导与练习
(图片来源网络,侵删)

1 选择开发环境

对于初学者,推荐以下两种:

  • 集成开发环境 - 强烈推荐

    • Visual Studio (VS):功能强大,调试工具无敌,适合Windows用户,安装时请勾选“使用C++的桌面开发” workload。
    • Dev-C++:轻量级,简单易用,非常适合初学者。
    • Code::Blocks:开源、免费、跨平台,配置简单。
  • 命令行工具 + 编辑器

    • GCC (MinGW-w64):C语言的标准编译器,配合 VS CodeSublime Text 等编辑器使用,这种方式更接近底层,但对新手配置稍复杂。

2 第一个C程序:Hello, World!

目标:成功编译并运行一个最简单的程序,感受C语言的完整流程。

代码 (hello.c):

#include <stdio.h> // 1. 包含标准输入输出库
int main() {      // 2. 主函数,程序从这里开始执行
    printf("Hello, World!\n"); // 3. 调用printf函数在屏幕上打印文本
    return 0;     // 4. 返回0,表示程序正常结束
}

上机步骤 (以VS为例):

  1. 打开 Visual Studio。
  2. 创建新项目 -> 选择“控制台应用” -> 给项目命名 (如 HelloWorld)。
  3. VS会自动生成一个 .c 文件,将上面的代码复制进去。
  4. 按下 Ctrl + F5 (或点击“开始执行(不调试)”),程序就会运行并显示 "Hello, World!"。

上机要点:

  • #include <stdio.h>:告诉编译器,我要使用 printf 这个函数,这个函数的“说明书”在 stdio.h 文件里。
  • int main():程序的入口,必须有且只有一个。
  • printf(...):格式化输出函数, 里的内容原样输出,\n 表示换行。
  • (分号):C语句的结束符,绝对不能忘
  • (花括号):代码块的开始和结束,用来组织代码。

第二部分:核心知识点与上机指导

这是本指南的核心,请务必跟随指导,亲手敲代码,完成练习。

变量、数据类型与运算符

知识点:C语言的基本构成单元,变量是数据的容器,数据类型决定了容器的大小和能存放的东西,运算符是用来操作容器内数据的工具。

上机指导:

  1. 数据类型int (整数), float (单精度浮点数), double (双精度浮点数), char (单个字符)。
  2. 变量定义与赋值数据类型 变量名 = 初始值;
  3. 运算符
    • 算术:, , , , (取模)
    • 赋值:, , , ...
    • 自增/自减:,
    • 关系:>, <, ,
    • 逻辑:&& (与), (或), (非)

示例代码 (data_types.c):

#include <stdio.h>
int main() {
    // 1. 定义不同类型的变量
    int age = 25;
    float price = 99.98f; // f表示这是一个float常量
    double pi = 3.1415926;
    char grade = 'A';
    // 2. 使用printf输出
    // %d 用于输出整数
    // %f 用于输出浮点数
    // %c 用于输出字符
    // \t 制表符,用于对齐
    printf("年龄: %d\n", age);
    printf("价格: %f\n", price);
    printf("PI: %lf\n", pi); // lf 用于double
    printf("等级: %c\n", grade);
    // 3. 算术运算
    int a = 10, b = 3;
    printf("10 + 3 = %d\n", a + b);
    printf("10 - 3 = %d\n", a - b);
    printf("10 * 3 = %d\n", a * b);
    printf("10 / 3 = %d\n", a / b); // 整数除法,结果为整数
    printf("10 %% 3 = %d\n", a % b); // %% 用来输出 %
    return 0;
}

常见错误:

  • 未定义变量:直接使用一个没有声明的变量(如 printf("%d", x); 但没有 int x;)。
  • 数据类型不匹配:将一个浮点数赋值给整型变量,小数部分会丢失。
  • 忘记 :编译器会报错,提示信息可能指向下一行。
  • 和 的混淆: 是除法, 是取余, 只能用于整数。

上机练习:

  1. 定义两个整型变量 xy,分别赋值为 10 和 4,计算并输出它们的和、差、积、商、余数。
  2. 定义一个整型变量 i,初始值为0,使用 i++++i 分别给另一个变量 jk 赋值,观察 jk 的值有什么不同。
  3. 定义一个字符变量 ch,赋值为 'Z',计算并输出它的下一个字符是什么。

流程控制 - 让程序做选择和循环

知识点:控制程序执行流程的骨架,是编程的灵魂。

A. 条件语句

上机指导:

  • if-else:..否则...
  • switch:多路选择,适用于固定值的判断。

示例代码 (if_else.c):

#include <stdio.h>
int main() {
    int score;
    printf("请输入你的分数: ");
    scanf("%d", &score); // 从键盘读取一个整数存入score
    if (score >= 90) {
        printf("优秀!\n");
    } else if (score >= 60) {
        printf("及格!\n");
    } else {
        printf("不及格!\n");
    }
    return 0;
}

B. 循环语句

上机指导:

  • for循环:明确知道循环次数时使用。
  • while循环:在循环开始前判断条件,适合循环次数不确定的情况。
  • do-while循环:至少执行一次循环体,然后在循环结束时判断条件。

示例代码 (loops.c):

#include <stdio.h>
int main() {
    // 1. for循环:打印1到10
    printf("--- for循环 ---\n");
    for (int i = 1; i <= 10; i++) {
        printf("%d ", i);
    }
    printf("\n");
    // 2. while循环:计算1到100的和
    printf("\n--- while循环 ---\n");
    int sum = 0;
    int j = 1;
    while (j <= 100) {
        sum += j;
        j++;
    }
    printf("1到100的和是: %d\n", sum);
    // 3. do-while循环:至少执行一次
    printf("\n--- do-while循环 ---\n");
    int number;
    do {
        printf("请输入一个大于0的数字: ");
        scanf("%d", &number);
    } while (number <= 0); // 如果输入的数<=0,就继续循环
    printf("你输入的数字是: %d\n", number);
    return 0;
}

常见错误:

  • 逻辑表达式写错if (a = 5) 是将5赋值给a,并判断a是否为真(总是真),应该是 if (a == 5)
  • 循环条件永远为真:忘记在循环体内修改循环变量,导致“死循环”。
  • 的省略问题iffor 后面如果只有一条语句,可以省略 ,但强烈不推荐,很容易出错。

上机练习:

  1. 判断闰年:输入一个年份,判断它是否是闰年。(闰年规则:能被4整除但不能被100整除,或者能被400整除)。
  2. 打印九九乘法表:使用嵌套 for 循环打印标准的九九乘法表。
  3. 猜数字游戏:程序随机生成一个1-100的数字,用户输入猜测,程序提示“猜大了”或“猜小了”,直到猜中为止。(提示:需要 #include <stdlib.h>#include <time.h> 来生成随机数)。

数组

知识点:存储一组相同类型数据的集合。

上机指导:

  • 一维数组数据类型 数组名[元素个数];
  • 数组下标:从 0 开始。
  • 初始化int arr[5] = {1, 2, 3, 4, 5};
  • 遍历数组:使用 for 循环,下标从0到 长度-1

示例代码 (array_example.c):

#include <stdio.h>
int main() {
    // 1. 定义并初始化数组
    int scores[5] = {88, 92, 75, 99, 85};
    int sum = 0;
    double average;
    // 2. 遍历数组,计算总分
    printf("所有分数: ");
    for (int i = 0; i < 5; i++) {
        printf("%d ", scores[i]);
        sum += scores[i];
    }
    printf("\n");
    // 3. 计算并输出平均分
    average = (double)sum / 5; // 注意:将sum转换为double,以保证除法结果是浮点数
    printf("总分: %d\n", sum);
    printf("平均分: %.2lf\n", average); // .2lf 表示保留两位小数
    return 0;
}

常见错误:

  • 数组越界:访问数组时下标小于0或大于等于数组长度,会导致程序崩溃或不可预测的错误。
  • 数组大小必须是常量int n = 5; int arr[n]; 在标准C中是不允许的(C99标准后允许,但初学者应避免)。

上机练习:

  1. 数组元素逆序:定义一个数组,将其元素顺序颠倒后重新输出。
  2. 找出最大值和最小值:从键盘输入10个整数,存入数组,然后找出其中的最大值和最小值。
  3. 冒泡排序:实现冒泡排序算法,对一个数组进行升序排序。

函数

知识点:将一段代码封装起来,实现代码的复用和模块化。

上机指导:

  • 函数定义返回类型 函数名(参数列表) { 函数体 }
  • 函数声明返回类型 函数名(参数列表); (放在 main 函数之前)
  • 函数调用函数名(实际参数);
  • 参数传递:C语言是值传递,函数内部修改参数不会影响外部的变量。

示例代码 (function_example.c):

#include <stdio.h>
// 1. 函数声明
int add(int a, int b); // 声明一个名为add的函数,它接收两个int参数,返回一个int值
int main() {
    int num1 = 10, num2 = 20;
    int result;
    // 2. 函数调用
    result = add(num1, num2);
    printf("%d + %d = %d\n", num1, num2, result);
    return 0;
}
// 3. 函数定义
int add(int a, int b) {
    return a + b;
}

上机练习:

  1. 判断素数:编写一个函数 is_prime(int num)num 是素数,返回1,否则返回0,在 main 函数中调用它,判断用户输入的数字是否为素数。
  2. 数组求和:编写一个函数 array_sum(int arr[], int size),用来计算一个数组的所有元素之和。
  3. 交换两个变量:尝试编写一个函数 swap(int a, int b) 来交换两个变量的值,并思考为什么在 main 函数中看不到交换效果,然后学习使用指针来实现真正的交换。

指针 - C语言的精髓

知识点:存储另一个变量地址的变量,理解指针是理解C语言高级特性的关键。

上机指导:

  • & (取地址符):获取变量的内存地址。
  • *`` (解引用/间接访问符)**:通过指针访问它指向地址的值。
  • 指针定义数据类型 *指针名; (如 int *p;)
  • 指针与数组:数组名 arr 就是数组首元素的地址,arr[i] 等价于 *(arr + i)

示例代码 (pointer_example.c):

#include <stdio.h>
int main() {
    int var = 10;
    int *p; // 定义一个指向整型的指针p
    p = &var; // 将var的地址赋给p
    printf("var的值: %d\n", var);
    printf("var的地址: %p\n", &var);
    printf("指针p存储的地址: %p\n", p);
    printf("指针p指向的值: %d\n", *p); // 通过*p访问var的值
    // 修改指针指向的值
    *p = 20;
    printf("修改后var的值: %d\n", var); // var的值也变成了20
    return 0;
}

常见错误:

  • 未初始化的指针:使用一个没有指向任何有效地址的指针(野指针),会导致程序崩溃。
  • 指针类型不匹配:用一个 int* 指针去访问一个 double 变量的地址。
  • *忘记 `**:需要访问指针指向的值时,忘了写*`。

上机练习:

  1. 使用指针交换两个变量的值:编写 swap 函数,这次使用指针参数,实现真正的交换。
  2. 指针遍历数组:使用指针和指针的算术运算来遍历一个数组并打印所有元素。
  3. 理解 const 与指针:尝试定义 const int *p, int * const p, const int * const p 并理解它们的区别。

结构体

知识点:将不同类型的数据组合成一个有机的整体。

上机指导:

  • 定义结构体类型struct 结构体名 { 成员列表; };
  • 定义结构体变量struct 结构体名 变量名;
  • 访问成员变量名.成员名 (用 点操作符)

示例代码 (struct_example.c):

#include <stdio.h>
#include <string.h>
// 1. 定义一个名为Student的结构体
struct Student {
    int id;
    char name[50];
    float score;
};
int main() {
    // 2. 定义一个Student类型的变量s1
    struct Student s1;
    // 3. 给成员赋值
    s1.id = 1001;
    strcpy(s1.name, "张三"); // 字符串不能直接用=赋值,需要用strcpy
    s1.score = 95.5;
    // 4. 打印成员信息
    printf("学号: %d\n", s1.id);
    printf("姓名: %s\n", s1.name);
    printf("分数: %.2f\n", s1.score);
    return 0;
}

上机练习:

  1. 定义一个Book结构体,包含书名、作者、价格三个成员,定义一个Book变量并初始化,然后打印其信息。
  2. 结构体数组:创建一个包含3个Student结构体的数组,并遍历打印所有学生的信息。

第三部分:综合项目实践 - 学生成绩管理系统

目标:将所学知识融会贯通,开发一个小型控制台应用程序。

项目功能:

  1. 添加学生:输入学号、姓名、分数,添加到系统中。
  2. 显示所有学生:以表格形式列出所有学生的信息。
  3. 查找学生:按学号查找学生并显示其信息。
  4. 删除学生:按学号删除学生。
  5. 退出系统

项目结构思路:

  • 使用 struct Student 来存储单个学生信息。
  • 使用 struct Student students[100]; 来存储所有学生,int student_count = 0; 来记录当前学生数量。
  • 使用 while(1) 无限循环 + switch 语句来显示主菜单,并根据用户选择调用不同的功能函数。
  • 每个功能(添加、显示、查找、删除)都封装成一个独立的函数。

实践步骤:

  1. 定义 Student 结构体。
  2. 编写 show_menu() 函数,打印菜单。
  3. 编写 add_student() 函数。
  4. 编写 show_students() 函数。
  5. 编写 find_student() 函数。
  6. 编写 delete_student() 函数。
  7. main 函数中整合所有逻辑,实现主循环。

这个项目非常有挑战性,但完成后你的C语言水平会有质的飞跃。


第四部分:常见问题与调试技巧

1 常见编译错误 (新手必看)

错误信息 (可能类似) 中文含义 可能原因
error C2143: syntax error : missing ';' before '}' 语法错误:在 '}' 前缺少 ';' 最常见!语句末尾忘记写分号。
error C2065: 'xxx' : undeclared identifier 错误:'xxx' 是未声明的标识符 变量或函数名拼写错误,或未定义就使用。
error C2109: subscript requires array or pointer type 错误:下标操作需要数组或指针类型 对一个非数组类型使用了 [ ]
warning C4700: uninitialized local variable 'xxx' used 警告:使用了未初始化的局部变量 'xxx' 定义了变量但没有给它赋初值就使用它,值是随机的。
error C2660: 'function' : function does not take X arguments 错误:'function' 函数不接受 X 个参数 调用函数时传入的参数个数或类型不正确。

2 调试技巧

调试是程序员最重要的技能之一。

  1. printf 大法:最简单、最有效的调试方法。

    • 在怀疑出错的代码前后,加上 printf 语句,打印变量的值、程序的执行流程。
    • printf("进入循环前,i = %d\n", i);printf("交换前: a=%d, b=%d\n", a, b);
  2. 单步调试:使用IDE的调试功能。

    • 设置断点:在代码行号左边点击,会出现一个红点,程序运行到这一行会暂停。
    • 启动调试:按 F5 (VS) 或相应按钮。
    • 单步执行
      • F10 (逐过程):将当前函数(如果有的话)当作一个整体一步执行完。
      • F11 (逐语句):进入函数内部,一步一步地执行。
    • 监视变量:在调试过程中,可以随时查看变量的当前值,观察它是否按预期变化。
  3. 代码审查:逐行阅读自己的代码,模拟计算机的执行过程,逻辑上是否能走通?边界条件(如数组最后一个元素、循环的最后一次)是否考虑到了?

C语言的学习是一个螺旋式上升的过程,不要怕犯错,错误是最好的老师。多动手、多思考、多总结是学好编程的唯一捷径。

祝你学习顺利,早日成为C语言高手!

-- 展开阅读全文 --
头像
如何用C语言实现PID控制算法?
« 上一篇 昨天
dede用户名不存在怎么办?
下一篇 » 今天

相关文章

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

目录[+]