C 语言入门教程:从零开始,迈向编程世界
这份教程将带你系统地学习 C 语言,我们将从最基础的概念开始,逐步深入,最终让你能够独立编写 C 程序。

第一部分:准备工作与基础概念
第一章:C 语言简介与环境搭建
1 什么是 C 语言? C 语言是一种通用的、过程式的编程语言,它由 Dennis Ritchie 于 1972 年在贝尔实验室创建,C 语言被誉为“现代编程语言的鼻祖”,因为它深刻影响了后来的 C++、Java、C#、Python 等众多语言,它高效、灵活、功能强大,广泛应用于操作系统(如 Windows、Linux 内核)、嵌入式系统、游戏引擎等领域。
2 为什么学习 C 语言?
- 打下坚实基础:学习 C 能让你深刻理解计算机内存管理、指针等核心概念,这是学习其他高级语言的基础。
- 高效性能:C 语言允许直接操作硬件,运行效率极高。
- 广泛应用:掌握 C 语言是进入系统编程、嵌入式开发等领域的关键。
- 锻炼思维:C 语言对语法要求严格,能培养严谨的逻辑思维能力。
3 开发环境搭建 要编写和运行 C 程序,你需要两样东西:
- 编译器:将人类可读的 C 源代码翻译成机器可执行的文件。
- 文本编辑器/集成开发环境:用来编写代码。
推荐工具组合:

-
Windows 平台
- 编译器:MinGW-w64 (GCC 的 Windows 移植版)
- IDE (集成开发环境):Visual Studio Code (VS Code) 或 Dev-C++
- 安装步骤:
- 安装 VS Code。
- 安装 MinGW-w64,并将其
bin目录添加到系统环境变量PATH中。 - 在 VS Code 中安装 "C/C++" 扩展。
-
macOS 平台
- 编译器:Xcode Command Line Tools (已包含 Clang 编译器)
- IDE:Xcode (官方推荐,功能强大) 或 VS Code
- 安装步骤:在终端中运行
xcode-select --install。
-
Linux 平台
- 编译器:GCC (GNU Compiler Collection)
- IDE:VS Code, Geany, Code::Blocks 或使用
vim/nano+gcc命令行。 - 安装步骤 (以 Ubuntu 为例):在终端运行
sudo apt update && sudo apt install build-essential。
第二章:你的第一个 C 程序 - "Hello, World!"
让我们从一个最简单的程序开始,感受一下 C 语言的结构。

// my_first_program.c
#include <stdio.h> // 1. 包含标准输入输出库
int main(void) { // 2. 主函数,程序从这里开始执行
printf("Hello, World!\n"); // 3. 调用 printf 函数在屏幕上打印文本
return 0; // 4. 返回 0,表示程序正常结束
}
代码详解:
#include <stdio.h>:这是一个预处理指令。stdio.h是一个“头文件”,包含了printf函数的声明,没有它,编译器就不知道printf是什么。int main(void):这是程序的主函数。int表示这个函数执行完毕后会返回一个整数(return 0)。void表示main函数不接受任何参数,一个 C 程序必须有且只有一个main函数。printf("Hello, World!\n");:printf是一个标准库函数,用于格式化输出。"Hello, World!"是要打印的字符串。\n是一个转义字符,代表“换行”。return 0;:向操作系统返回 0,表示程序成功执行完毕。
如何编译和运行?
- 将上述代码保存为
my_first_program.c。 - 打开终端(或命令提示符),进入文件所在的目录。
- 输入编译命令:
gcc my_first_program.c -o my_first_program
gcc:编译器名称。my_first_program.c:你的源文件。-o my_first_program:指定输出的可执行文件名。
- 运行生成的程序:
- Windows:
my_first_program.exe - macOS/Linux:
./my_first_program
- Windows:
你应该会在终端看到 Hello, World! 的输出。
第二部分:C 语言核心语法
第三章:变量与数据类型
1 变量 变量是内存中一个命名的存储位置,用于存储数据,使用变量前必须先声明。
int age; // 声明一个整型变量 age float price; // 声明一个单精度浮点型变量 price char grade; // 声明一个字符型变量 grade age = 25; // 赋值 price = 19.99; grade = 'A'; // 字符用单引号括起来
2 基本数据类型
| 类型 | 关键字 | 描述 | 大小( | 示例 |
| :--- | :--- | :--- | :--- | :--- |
| 整型 | int | 存储整数 | 4 字节 | 10, -100 |
| 字符型 | char | 存储单个字符 | 1 字节 | 'a', '0' |
| 浮点型 | float | 存储单精度浮点数(小数) | 4 字节 | 14, -0.5 |
| 双精度浮点型 | double | 存储双精度浮点数(更高精度) | 8 字节 | 14159265 |
| 无类型 | void | 表示“无类型” | - | 用于函数返回值 |
3 常量 常量是其值在程序运行期间不能改变的量。
const int MAX_AGE = 120; // 使用 const 关键字定义整型常量 #define PI 3.14159 // 使用预处理指令定义宏常量
第四章:运算符
C 语言提供了丰富的运算符来执行各种操作。
1 算术运算符
- (加), (减), (乘), (除), (取模,求余数)
int a = 10, b = 3; printf("%d\n", a / b); // 输出 3 (整数除法会截断小数部分) printf("%d\n", a % b); // 输出 1 (10 除以 3 的余数是 1)
2 赋值运算符
- , , , , , (复合赋值)
int x = 5; x += 3; // 等价于 x = x + 3; x 的值变为 8
3 关系运算符
- (等于), (不等于),
>(大于),<(小于),>=(大于等于),<=(小于等于)- 注意: 用于比较是否相等, 用于赋值,这是最常见的初学者错误。
int age = 18; if (age == 18) { printf("You are 18.\n"); }
- 注意: 用于比较是否相等, 用于赋值,这是最常见的初学者错误。
4 逻辑运算符
&&(逻辑与), (逻辑或), (逻辑非)int age = 20; if (age > 18 && age < 60) { printf("You are an adult.\n"); }
第五章:输入与输出
我们已经在 Hello, World 中使用了 printf,现在我们来学习 scanf 用于输入。
1 printf - 格式化输出
printf 的格式:printf("格式化字符串", 变量列表);
%d:用于输出整数 (int)%f:用于输出浮点数 (float,double)%c:用于输出字符 (char)%s:用于输出字符串 (char[])
int number = 100;
float pi = 3.14159;
printf("The number is %d and pi is %.2f\n", number, pi); // %.2f 表示保留两位小数
2 scanf - 格式化输入
scanf 的格式:scanf("格式化字符串", &变量地址列表);
- 关键:
&是取地址运算符,你必须提供变量的地址,scanf才能把输入的值存入该变量对应的内存位置。
int age;
printf("Please enter your age: ");
scanf("%d", &age); // 从键盘读取一个整数,存入 age 变量中
printf("You entered: %d\n", age);
第六章:控制流
1 条件语句
if-elseint score = 85; if (score >= 90) { printf("Grade: A\n"); } else if (score >= 80) { printf("Grade: B\n"); } else { printf("Grade: C or below\n"); }switchchar grade = 'B'; switch (grade) { case 'A': printf("Excellent!\n"); break; // 不要忘记 break! case 'B': printf("Good job!\n"); break; default: printf("Keep trying!\n"); }
2 循环语句
for循环 (适合已知循环次数的场景)for (int i = 0; i < 5; i++) { // 初始化; 条件; 更新 printf("Iteration %d\n", i); }while循环 (适合在循环开始前不确定次数的场景)int count = 0; while (count < 5) { printf("Count is %d\n", count); count++; // 别忘记更新循环变量! }do-while循环 (至少执行一次)int number = 0; do { printf("Enter a positive number: "); scanf("%d", &number); } while (number <= 0);
第三部分:C 语言进阶特性
第七章:函数
函数是组织好的、可重复使用的、用来执行特定任务的代码块。
1 函数的定义与调用
// 函数声明 (可选,如果函数定义在 main 之后)
int add(int a, int b);
int main(void) {
int result = add(5, 3); // 函数调用
printf("Result: %d\n", result);
return 0;
}
// 函数定义
int add(int a, int b) { // int 是返回类型,add 是函数名,(int a, int b) 是参数列表
int sum = a + b;
return sum; // 返回计算结果
}
2 函数参数传递 C 语言中,函数参数传递是“值传递” (Pass-by-Value),这意味着函数内部操作的是原始值的一个副本,不会改变原始变量。
第八章:数组
数组是一组相同类型元素的集合,在内存中连续存放。
1 一维数组
int scores[5]; // 声明一个包含 5 个整数的数组
// 初始化
int numbers[5] = {10, 20, 30, 40, 50};
int more_numbers[] = {1, 2, 3}; // 编译器会自动确定数组大小为 3
// 访问元素
printf("First number: %d\n", numbers[0]); // 数组索引从 0 开始
numbers[0] = 100; // 修改第一个元素
2 字符串
在 C 语言中,字符串本质上是字符数组,以空字符 指针是 C 语言最强大也最容易出错的概念,它是一个变量,其值为另一个变量的地址。 1 指针基础 2 指针与数组
数组名在表达式中会“退化”为其首元素的地址。 3 指针与函数
通过指针传递参数,可以在函数内部修改外部变量的值(模拟“引用传递”)。 1 结构体
结构体允许你将不同类型的数据组合成一个单一的、自定义的类型。 C 语言提供了手动管理内存的强大功能,但也带来了风险。 重要:任何 C 语言可以轻松地对文件进行读写操作。 这份教程为你勾勒了 C 语言学习的完整蓝图,最重要的是动手实践,多写代码,多调试错误,祝你学习顺利!'\0'
char greeting[6] = "Hello"; // 'H','e','l','l','o','\0'
char name[] = "Alice"; // 编译器会自动分配空间,包括 '\0'
// 使用 %s 输出字符串
printf("%s\n", greeting);
第九章:指针 - C 语言的灵魂
int age = 25;
int *ptr_age = &age; // 声明一个整型指针 ptr_age,并初始化为 age 的地址
// * (解引用运算符)
printf("Value of age: %d\n", *ptr_age); // 通过指针访问 age 的值
*ptr_age = 30; // 通过指针修改 age 的值
printf("New value of age: %d\n", age); // age 的值现在变成了 30
int arr[3] = {10, 20, 30};
int *ptr = arr; // ptr 指向 arr 的第一个元素
printf("First element: %d\n", *ptr);
printf("Second element: %d\n", *(ptr + 1)); // 指针加 1,指向下一个元素
void swap(int *a, int *b) {
int temp = *a;
*a = *b;
*b = temp;
}
int main(void) {
int x = 10, y = 20;
printf("Before swap: x=%d, y=%d\n", x, y);
swap(&x, &y); // 传递变量的地址
printf("After swap: x=%d, y=%d\n", x, y);
return 0;
}
第十章:结构体、联合体与枚举
struct Student {
char name[50];
int age;
float gpa;
};
int main(void) {
struct Student student1; // 声明一个 Student 类型的变量
strcpy(student1.name, "Bob"); // 使用 strcpy 安全地复制字符串
student1.age = 20;
student1.gpa = 3.8;
printf("Name: %s, Age: %d, GPA: %.2f\n", student1.name, student1.age, student1.gpa);
return 0;
}
第四部分:实践与进阶
第十一章:内存管理
malloc (Memory Allocate): 在堆上分配一块指定大小的内存。free: 释放由 malloc 分配的内存,防止内存泄漏。#include <stdlib.h> // 需要 stdlib.h
int main(void) {
int *ptr;
int n = 5;
// 分配 5 个整数的内存空间
ptr = (int*) malloc(n * sizeof(int));
if (ptr == NULL) {
printf("Memory not allocated.\n");
return 1;
}
// 使用分配的内存
for (int i = 0; i < n; ++i) {
ptr[i] = i + 1;
}
// 打印内存内容
for (int i = 0; i < n; ++i) {
printf("%d ", ptr[i]);
}
// 释放内存
free(ptr);
return 0;
}
malloc 的内存,最终都必须 free,否则会导致内存泄漏。第十二章:文件 I/O
fopen: 打开一个文件,返回一个 FILE* 指针。fprintf, fscanf: 类似 printf 和 scanf,但操作的是文件。fputs, fgets: 操作字符串。fclose: 关闭文件。#include <stdio.h>
int main(void) {
FILE *fp;
char filename[] = "my_file.txt";
// 写入文件
fp = fopen(filename, "w"); // "w" 表示写入模式(覆盖)
if (fp == NULL) {
printf("Could not open file for writing.\n");
return 1;
}
fprintf(fp, "Hello, this is a test.\n");
fprintf(fp, "This is the second line.\n");
fclose(fp);
// 读取文件
fp = fopen(filename, "r"); // "r" 表示读取模式
if (fp == NULL) {
printf("Could not open file for reading.\n");
return 1;
}
char buffer[100];
while (fgets(buffer, sizeof(buffer), fp) != NULL) {
printf("%s", buffer);
}
fclose(fp);
return 0;
}
学习路径建议
<stdlib.h>, <string.h>, <math.h> 等标准库的功能。
