C语言完整教学文档
目录
一、C语言简介
1.1 什么是C语言
C语言是一种通用的、过程式的计算机编程语言,由Dennis Ritchie于1972年在贝尔实验室开发,最初用于编写UNIX操作系统。
1.2 C语言特点
特点 说明 高效性 接近硬件,执行速度快 可移植性 可在不同平台上运行 灵活性 既能进行底层操作,又能实现复杂算法 基础性 很多现代语言(C++、Java、Python)都受C影响 广泛应用 操作系统、嵌入式、游戏引擎等
1.3 C语言应用领域
C语言应用
操作系统
嵌入式系统
编译器开发
数据库系统
网络编程
游戏引擎
驱动程序
Linux/Unix
单片机/物联网
GCC/LLVM
MySQL/Redis
1.4 C语言发展历程
年份 版本 重要特性 1972 诞生 Dennis Ritchie开发 1978 K&R C 《The C Programming Language》出版 1989 ANSI C (C89) 第一个标准化版本 1999 C99 添加新数据类型、变长数组等 2011 C11 多线程支持、改进Unicode 2018 C18 Bug修复和澄清
二、开发环境搭建
2.1 Windows环境
方法1:安装MinGW
1 . 下载MinGW安装器
访问:https://sourceforge.net/projects/mingw/
2 . 安装GCC编译器
- 选择 mingw32-gcc-g++
- 选择 mingw32-base
3 . 配置环境变量
将 C:\ MinGW\ bin 添加到系统PATH
4 . 验证安装
打开命令提示符,输入:
gcc --version
方法2:安装Visual Studio
1. 下载Visual Studio Community(免费)
https://visualstudio.microsoft.com/
2. 安装时选择"使用C++的桌面开发"
3. 创建C项目
文件 -> 新建 -> 项目 -> C++空项目
添加.c文件即可
方法3:使用Dev-C++(推荐初学者)
1. 下载Dev-C++
https://sourceforge.net/projects/orwelldevcpp/
2. 安装并启动
3. 创建新项目
文件 -> 新建 -> 项目 -> Console Application
2.2 macOS环境
xcode-select --install
gcc --version
clang --version
echo '#include <stdio.h>
int main() {
printf("Hello, World!\\ n");
return 0;
}' > hello.c
gcc hello.c -o hello
./hello
2.3 Linux环境
sudo apt update
sudo apt install build-essential
sudo yum groupinstall "Development Tools"
gcc --version
gcc hello.c -o hello
./hello
2.4 在线编译器(无需安装)
三、基础语法
3.1 第一个C程序
# include <stdio.h>
int main ( ) {
printf ( "Hello, World!\n" ) ;
return 0 ;
}
### 3.2 编译与运行
```bash
# 编译(生成可执行文件)
gcc hello.c -o hello
# 运行
./hello # Linux/macOS
hello.exe # Windows
# 一步编译运行(仅生成临时文件)
gcc hello.c && ./a.out
3.3 注释
int add ( int a, int b) {
return a + b;
}
3.4 标识符命名规则
int age;
int _count;
int studentAge;
int student_age;
int value123;
命名规范 :
类型 命名风格 示例 变量 小写+下划线 student_count常量 全大写+下划线 MAX_SIZE函数 小写+下划线 calculate_sum宏 全大写+下划线 PI_VALUE
3.5 关键字
C语言有32个关键字,不能用作标识符:
auto break case char const continue
default do double else enum extern
float for goto if int long
register return short signed sizeof static
struct switch typedef union unsigned void
volatile while
四、数据类型与运算符
4.1 基本数据类型
# include <stdio.h>
int main ( ) {
int age = 25 ;
short height = 170 ;
long population = 1400000000L ;
long long bigNumber = 9223372036854775807LL ;
char grade = 'A' ;
float pi = 3.14159f ;
double e = 2.718281828 ;
unsigned int count = 100 ;
printf ( "int: %zu bytes\n" , sizeof ( int ) ) ;
printf ( "char: %zu bytes\n" , sizeof ( char ) ) ;
printf ( "float: %zu bytes\n" , sizeof ( float ) ) ;
printf ( "double: %zu bytes\n" , sizeof ( double ) ) ;
return 0 ;
}
数据类型范围表 :
类型 大小 范围 char1字节 -128 到 127 unsigned char1字节 0 到 255 short2字节 -32,768 到 32,767 int4字节 -2,147,483,648 到 2,147,483,647 long4/8字节 取决于系统 float4字节 3.4E-38 到 3.4E+38 double8字节 1.7E-308 到 1.7E+308
4.2 格式化输出
# include <stdio.h>
int main ( ) {
int num = 42 ;
float pi = 3.14159 ;
char ch = 'A' ;
char str[ ] = "Hello" ;
printf ( "整数: %d\n" , num) ;
printf ( "浮点数: %f\n" , pi) ;
printf ( "字符: %c\n" , ch) ;
printf ( "字符串: %s\n" , str) ;
printf ( "八进制: %o\n" , num) ;
printf ( "十六进制: %x\n" , num) ;
printf ( "十六进制(大写): %X\n" , num) ;
printf ( "右对齐: %5d\n" , num) ;
printf ( "左对齐: %-5d\n" , num) ;
printf ( "补零: %05d\n" , num) ;
printf ( "保留2位小数: %.2f\n" , pi) ;
printf ( "宽度10,2位小数: %10.2f\n" , pi) ;
return 0 ;
}
4.3 算术运算符
# include <stdio.h>
int main ( ) {
int a = 10 , b = 3 ;
printf ( "加法: %d + %d = %d\n" , a, b, a + b) ;
printf ( "减法: %d - %d = %d\n" , a, b, a - b) ;
printf ( "乘法: %d * %d = %d\n" , a, b, a * b) ;
printf ( "除法: %d / %d = %d\n" , a, b, a / b) ;
printf ( "取余: %d %% %d = %d\n" , a, b, a % b) ;
float result = ( float ) a / b;
printf ( "浮点除法: %.2f\n" , result) ;
int x = 5 ;
printf ( "x++: %d\n" , x++ ) ;
printf ( "++x: %d\n" , ++ x) ;
return 0 ;
}
4.4 关系运算符
# include <stdio.h>
int main ( ) {
int a = 5 , b = 10 ;
printf ( "%d == %d: %d\n" , a, b, a == b) ;
printf ( "%d != %d: %d\n" , a, b, a != b) ;
printf ( "%d > %d: %d\n" , a, b, a > b) ;
printf ( "%d < %d: %d\n" , a, b, a < b) ;
printf ( "%d >= %d: %d\n" , a, b, a >= b) ;
printf ( "%d <= %d: %d\n" , a, b, a <= b) ;
return 0 ;
}
4.5 逻辑运算符
# include <stdio.h>
int main ( ) {
int x = 5 , y = 10 , z = 15 ;
if ( x < y && y < z) {
printf ( "x < y < z\n" ) ;
}
if ( x > 10 || y > 5 ) {
printf ( "至少一个条件为真\n" ) ;
}
if ( ! ( x > y) ) {
printf ( "x 不大于 y\n" ) ;
}
return 0 ;
}
4.6 位运算符
# include <stdio.h>
void printBinary ( int n) {
for ( int i = 31 ; i >= 0 ; i-- ) {
printf ( "%d" , ( n >> i) & 1 ) ;
if ( i % 4 == 0 ) printf ( " " ) ;
}
printf ( "\n" ) ;
}
int main ( ) {
int a = 12 ;
int b = 10 ;
printf ( "a = 12: " ) ;
printBinary ( a) ;
printf ( "b = 10: " ) ;
printBinary ( b) ;
printf ( "\na & b (按位与): %d\n" , a & b) ;
printf ( "a | b (按位或): %d\n" , a | b) ;
printf ( "a ^ b (按位异或): %d\n" , a ^ b) ;
printf ( "~a (按位取反): %d\n" , ~ a) ;
printf ( "a << 1 (左移): %d\n" , a << 1 ) ;
printf ( "a >> 1 (右移): %d\n" , a >> 1 ) ;
return 0 ;
}
4.7 运算符优先级
优先级 运算符 说明 1 () [] -> .括号、数组、成员访问 2 ! ~ ++ -- + - * &一元运算符 3 * / %乘除模 4 + -加减 5 << >>位移 6 < <= > >=关系 7 == !=相等 8 &按位与 9 ^按位异或 10 |按位或 11 &&逻辑与 12 ||逻辑或 13 ?:三元条件 14 = += -= 等赋值
五、控制流程
5.1 if语句
# include <stdio.h>
int main ( ) {
int score = 85 ;
if ( score >= 60 ) {
printf ( "及格\n" ) ;
}
if ( score >= 60 ) {
printf ( "及格\n" ) ;
} else {
printf ( "不及格\n" ) ;
}
if ( score >= 90 ) {
printf ( "优秀\n" ) ;
} else if ( score >= 80 ) {
printf ( "良好\n" ) ;
} else if ( score >= 70 ) {
printf ( "中等\n" ) ;
} else if ( score >= 60 ) {
printf ( "及格\n" ) ;
} else {
printf ( "不及格\n" ) ;
}
if ( score >= 60 ) {
if ( score >= 90 ) {
printf ( "优秀及格\n" ) ;
} else {
printf ( "普通及格\n" ) ;
}
}
char * result = ( score >= 60 ) ? "及格" : "不及格" ;
printf ( "%s\n" , result) ;
return 0 ;
}
5.2 switch语句
# include <stdio.h>
int main ( ) {
int day = 3 ;
switch ( day) {
case 1 :
printf ( "星期一\n" ) ;
break ;
case 2 :
printf ( "星期二\n" ) ;
break ;
case 3 :
printf ( "星期三\n" ) ;
break ;
case 4 :
printf ( "星期四\n" ) ;
break ;
case 5 :
printf ( "星期五\n" ) ;
break ;
case 6 :
case 7 :
printf ( "周末\n" ) ;
break ;
default :
printf ( "无效的日期\n" ) ;
}
char grade = 'B' ;
switch ( grade) {
case 'A' :
printf ( "优秀\n" ) ;
break ;
case 'B' :
printf ( "良好\n" ) ;
break ;
case 'C' :
printf ( "中等\n" ) ;
break ;
default :
printf ( "需要努力\n" ) ;
}
return 0 ;
}
5.3 while循环
# include <stdio.h>
int main ( ) {
int i = 1 ;
while ( i <= 5 ) {
printf ( "%d " , i) ;
i++ ;
}
printf ( "\n" ) ;
int sum = 0 , n = 1 ;
while ( n <= 100 ) {
sum += n;
n++ ;
}
printf ( "1到100的和: %d\n" , sum) ;
int num;
do {
printf ( "请输入正数(输入0结束): " ) ;
scanf ( "%d" , & num) ;
printf ( "你输入了: %d\n" , num) ;
} while ( num != 0 ) ;
return 0 ;
}
5.4 for循环
# include <stdio.h>
int main ( ) {
for ( int i = 1 ; i <= 5 ; i++ ) {
printf ( "%d " , i) ;
}
printf ( "\n" ) ;
for ( int i = 5 ; i >= 1 ; i-- ) {
printf ( "%d " , i) ;
}
printf ( "\n" ) ;
for ( int i = 0 ; i <= 10 ; i += 2 ) {
printf ( "%d " , i) ;
}
printf ( "\n" ) ;
for ( int i = 1 ; i <= 9 ; i++ ) {
for ( int j = 1 ; j <= i; j++ ) {
printf ( "%d*%d=%d\t" , j, i, i* j) ;
}
printf ( "\n" ) ;
}
return 0 ;
}
5.5 循环控制
# include <stdio.h>
int main ( ) {
for ( int i = 1 ; i <= 10 ; i++ ) {
if ( i == 5 ) {
break ;
}
printf ( "%d " , i) ;
}
printf ( "\n" ) ;
for ( int i = 1 ; i <= 10 ; i++ ) {
if ( i % 2 == 0 ) {
continue ;
}
printf ( "%d " , i) ;
}
printf ( "\n" ) ;
int count = 0 ;
start:
printf ( "%d " , count) ;
count++ ;
if ( count < 5 ) {
goto start;
}
printf ( "\n" ) ;
return 0 ;
}
5.6 控制流程图
真
假
是
否
是
否
开始
条件判断
执行语句块
跳过
遇到break?
退出循环
遇到continue?
继续执行
结束
六、函数
6.1 函数定义
# include <stdio.h>
int add ( int a, int b) ;
void greet ( void ) ;
int max ( int a, int b) ;
int main ( ) {
int sum = add ( 5 , 3 ) ;
printf ( "5 + 3 = %d\n" , sum) ;
greet ( ) ;
int maximum = max ( 10 , 20 ) ;
printf ( "最大值: %d\n" , maximum) ;
return 0 ;
}
int add ( int a, int b) {
return a + b;
}
void greet ( void ) {
printf ( "Hello, World!\n" ) ;
}
int max ( int a, int b) {
return ( a > b) ? a : b;
}
6.2 函数参数传递
# include <stdio.h>
void swapByValue ( int a, int b) {
int temp = a;
a = b;
b = temp;
printf ( "函数内: a=%d, b=%d\n" , a, b) ;
}
void swapByPointer ( int * a, int * b) {
int temp = * a;
* a = * b;
* b = temp;
}
int main ( ) {
int x = 5 , y = 10 ;
printf ( "交换前: x=%d, y=%d\n" , x, y) ;
swapByValue ( x, y) ;
printf ( "值传递后: x=%d, y=%d\n" , x, y) ;
swapByPointer ( & x, & y) ;
printf ( "地址传递后: x=%d, y=%d\n" , x, y) ;
return 0 ;
}
6.3 递归函数
# include <stdio.h>
int factorial ( int n) {
if ( n == 0 || n == 1 ) {
return 1 ;
}
return n * factorial ( n - 1 ) ;
}
int fibonacci ( int n) {
if ( n == 0 ) return 0 ;
if ( n == 1 ) return 1 ;
return fibonacci ( n - 1 ) + fibonacci ( n - 2 ) ;
}
void hanoi ( int n, char from, char to, char aux) {
if ( n == 1 ) {
printf ( "移动盘子1从 %c 到 %c\n" , from, to) ;
return ;
}
hanoi ( n - 1 , from, aux, to) ;
printf ( "移动盘子%d从 %c 到 %c\n" , n, from, to) ;
hanoi ( n - 1 , aux, to, from) ;
}
int main ( ) {
printf ( "5! = %d\n" , factorial ( 5 ) ) ;
printf ( "斐波那契数列前10项: " ) ;
for ( int i = 0 ; i < 10 ; i++ ) {
printf ( "%d " , fibonacci ( i) ) ;
}
printf ( "\n" ) ;
printf ( "\n汉诺塔(3个盘子):\n" ) ;
hanoi ( 3 , 'A' , 'C' , 'B' ) ;
return 0 ;
}
6.4 可变参数函数
# include <stdio.h>
# include <stdarg.h>
int sum ( int count, . . . ) {
va_list args;
va_start ( args, count) ;
int total = 0 ;
for ( int i = 0 ; i < count; i++ ) {
total += va_arg ( args, int ) ;
}
va_end ( args) ;
return total;
}
int max ( int count, . . . ) {
va_list args;
va_start ( args, count) ;
int maximum = va_arg ( args, int ) ;
for ( int i = 1 ; i < count; i++ ) {
int value = va_arg ( args, int ) ;
if ( value > maximum) {
maximum = value;
}
}
va_end ( args) ;
return maximum;
}
int main ( ) {
printf ( "2个数的和: %d\n" , sum ( 2 , 10 , 20 ) ) ;
printf ( "5个数的和: %d\n" , sum ( 5 , 1 , 2 , 3 , 4 , 5 ) ) ;
printf ( "最大值: %d\n" , max ( 4 , 10 , 50 , 30 , 20 ) ) ;
return 0 ;
}
七、数组与字符串
7.1 一维数组
# include <stdio.h>
int main ( ) {
int arr1[ 5 ] ;
int arr2[ 5 ] = { 1 , 2 , 3 , 4 , 5 } ;
int arr3[ ] = { 1 , 2 , 3 } ;
int arr4[ 5 ] = { 1 , 2 } ;
printf ( "arr2[0] = %d\n" , arr2[ 0 ] ) ;
arr2[ 0 ] = 10 ;
printf ( "修改后 arr2[0] = %d\n" , arr2[ 0 ] ) ;
printf ( "数组元素: " ) ;
for ( int i = 0 ; i < 5 ; i++ ) {
printf ( "%d " , arr2[ i] ) ;
}
printf ( "\n" ) ;
int len = sizeof ( arr2) / sizeof ( arr2[ 0 ] ) ;
printf ( "数组长度: %d\n" , len) ;
int sum = 0 ;
for ( int i = 0 ; i < 5 ; i++ ) {
sum += arr2[ i] ;
}
printf ( "数组和: %d\n" , sum) ;
int max = arr2[ 0 ] ;
for ( int i = 1 ; i < 5 ; i++ ) {
if ( arr2[ i] > max) {
max = arr2[ i] ;
}
}
printf ( "最大值: %d\n" , max) ;
return 0 ;
}
7.2 二维数组
# include <stdio.h>
int main ( ) {
int matrix[ 3 ] [ 4 ] = {
{ 1 , 2 , 3 , 4 } ,
{ 5 , 6 , 7 , 8 } ,
{ 9 , 10 , 11 , 12 }
} ;
printf ( "matrix[1][2] = %d\n" , matrix[ 1 ] [ 2 ] ) ;
printf ( "矩阵:\n" ) ;
for ( int i = 0 ; i < 3 ; i++ ) {
for ( int j = 0 ; j < 4 ; j++ ) {
printf ( "%3d " , matrix[ i] [ j] ) ;
}
printf ( "\n" ) ;
}
int transpose[ 4 ] [ 3 ] ;
for ( int i = 0 ; i < 3 ; i++ ) {
for ( int j = 0 ; j < 4 ; j++ ) {
transpose[ j] [ i] = matrix[ i] [ j] ;
}
}
printf ( "\n转置矩阵:\n" ) ;
for ( int i = 0 ; i < 4 ; i++ ) {
for ( int j = 0 ; j < 3 ; j++ ) {
printf ( "%3d " , transpose[ i] [ j] ) ;
}
printf ( "\n" ) ;
}
return 0 ;
}
7.3 字符串基础
# include <stdio.h>
# include <string.h>
int main ( ) {
char str1[ ] = "Hello" ;
char str2[ 10 ] = "World" ;
char str3[ ] = { 'H' , 'i' , '\0' } ;
printf ( "%s\n" , str1) ;
printf ( "%s\n" , str2) ;
printf ( "str1长度: %zu\n" , strlen ( str1) ) ;
char dest[ 20 ] ;
strcpy ( dest, str1) ;
printf ( "复制后: %s\n" , dest) ;
strcat ( dest, " " ) ;
strcat ( dest, str2) ;
printf ( "拼接后: %s\n" , dest) ;
if ( strcmp ( str1, str2) == 0 ) {
printf ( "字符串相同\n" ) ;
} else {
printf ( "字符串不同\n" ) ;
}
char * pos = strstr ( dest, "World" ) ;
if ( pos != NULL ) {
printf ( "找到World,位置: %ld\n" , pos - dest) ;
}
return 0 ;
}
7.4 字符串常用函数
# include <stdio.h>
# include <string.h>
# include <ctype.h>
int main ( ) {
char str[ ] = "Hello, World!" ;
printf ( "长度: %zu\n" , strlen ( str) ) ;
char copy[ 50 ] ;
strcpy ( copy, str) ;
char partial[ 10 ] ;
strncpy ( partial, str, 5 ) ;
partial[ 5 ] = '\0' ;
printf ( "前5个字符: %s\n" , partial) ;
strcat ( copy, " Welcome!" ) ;
printf ( "拼接后: %s\n" , copy) ;
printf ( "strcmp结果: %d\n" , strcmp ( "abc" , "abc" ) ) ;
char * ch = strchr ( str, 'W' ) ;
if ( ch) printf ( "找到W: %s\n" , ch) ;
char * sub = strstr ( str, "World" ) ;
if ( sub) printf ( "找到World: %s\n" , sub) ;
char upper[ 50 ] ;
strcpy ( upper, str) ;
for ( int i = 0 ; upper[ i] ; i++ ) {
upper[ i] = toupper ( upper[ i] ) ;
}
printf ( "大写: %s\n" , upper) ;
for ( int i = 0 ; upper[ i] ; i++ ) {
upper[ i] = tolower ( upper[ i] ) ;
}
printf ( "小写: %s\n" , upper) ;
return 0 ;
}
7.5 字符串数组
# include <stdio.h>
# include <string.h>
int main ( ) {
char * fruits[ ] = {
"Apple" ,
"Banana" ,
"Cherry" ,
"Date"
} ;
int count = sizeof ( fruits) / sizeof ( fruits[ 0 ] ) ;
printf ( "水果列表:\n" ) ;
for ( int i = 0 ; i < count; i++ ) {
printf ( "%d. %s\n" , i+ 1 , fruits[ i] ) ;
}
char names[ 3 ] [ 20 ] = {
"Alice" ,
"Bob" ,
"Charlie"
} ;
printf ( "\n名字列表:\n" ) ;
for ( int i = 0 ; i < 3 ; i++ ) {
printf ( "%s\n" , names[ i] ) ;
}
char * items[ ] = { "Zebra" , "Apple" , "Mango" , "Banana" } ;
int n = 4 ;
for ( int i = 0 ; i < n- 1 ; i++ ) {
for ( int j = 0 ; j < n- i- 1 ; j++ ) {
if ( strcmp ( items[ j] , items[ j+ 1 ] ) > 0 ) {
char * temp = items[ j] ;
items[ j] = items[ j+ 1 ] ;
items[ j+ 1 ] = temp;
}
}
}
printf ( "\n排序后:\n" ) ;
for ( int i = 0 ; i < n; i++ ) {
printf ( "%s\n" , items[ i] ) ;
}
return 0 ;
}
八、指针
8.1 指针基础
# include <stdio.h>
int main ( ) {
int num = 42 ;
int * ptr;
ptr = & num;
printf ( "num的值: %d\n" , num) ;
printf ( "num的地址: %p\n" , ( void * ) & num) ;
printf ( "ptr存储的地址: %p\n" , ( void * ) ptr) ;
printf ( "ptr指向的值: %d\n" , * ptr) ;
* ptr = 100 ;
printf ( "修改后num的值: %d\n" , num) ;
printf ( "指针大小: %zu bytes\n" , sizeof ( ptr) ) ;
return 0 ;
}
8.2 指针与数组
# include <stdio.h>
int main ( ) {
int arr[ ] = { 10 , 20 , 30 , 40 , 50 } ;
int * ptr = arr;
printf ( "第一个元素: %d\n" , * ptr) ;
printf ( "第二个元素: %d\n" , * ( ptr + 1 ) ) ;
printf ( "数组元素: " ) ;
for ( int i = 0 ; i < 5 ; i++ ) {
printf ( "%d " , * ( ptr + i) ) ;
}
printf ( "\n" ) ;
printf ( "\n指针移动:\n" ) ;
ptr = arr;
printf ( "*ptr = %d\n" , * ptr) ;
ptr++ ;
printf ( "*ptr = %d\n" , * ptr) ;
ptr += 2 ;
printf ( "*ptr = %d\n" , * ptr) ;
return 0 ;
}
8.3 指针与字符串
# include <stdio.h>
# include <string.h>
int main ( ) {
char * str1 = "Hello" ;
char str2[ ] = "World" ;
printf ( "str1: %s\n" , str1) ;
printf ( "str2: %s\n" , str2) ;
str2[ 0 ] = 'w' ;
char * p = str2;
while ( * p != '\0' ) {
printf ( "%c " , * p) ;
p++ ;
}
printf ( "\n" ) ;
char * fruits[ ] = { "Apple" , "Banana" , "Cherry" } ;
for ( int i = 0 ; i < 3 ; i++ ) {
printf ( "%s\n" , fruits[ i] ) ;
}
return 0 ;
}
8.4 指针与函数
# include <stdio.h>
void swap ( int * a, int * b) {
int temp = * a;
* a = * b;
* b = temp;
}
void getMinMax ( int arr[ ] , int size, int * min, int * max) {
* min = * max = arr[ 0 ] ;
for ( int i = 1 ; i < size; i++ ) {
if ( arr[ i] < * min) * min = arr[ i] ;
if ( arr[ i] > * max) * max = arr[ i] ;
}
}
int * getMiddle ( int arr[ ] , int size) {
return & arr[ size/ 2 ] ;
}
int main ( ) {
int x = 5 , y = 10 ;
printf ( "交换前: x=%d, y=%d\n" , x, y) ;
swap ( & x, & y) ;
printf ( "交换后: x=%d, y=%d\n" , x, y) ;
int numbers[ ] = { 45 , 23 , 78 , 12 , 90 , 34 } ;
int min, max;
getMinMax ( numbers, 6 , & min, & max) ;
printf ( "最小值: %d, 最大值: %d\n" , min, max) ;
int * middle = getMiddle ( numbers, 6 ) ;
printf ( "中间元素: %d\n" , * middle) ;
return 0 ;
}
8.5 多级指针
# include <stdio.h>
int main ( ) {
int num = 42 ;
int * ptr1 = & num;
int * * ptr2 = & ptr1;
int * * * ptr3 = & ptr2;
printf ( "num = %d\n" , num) ;
printf ( "*ptr1 = %d\n" , * ptr1) ;
printf ( "**ptr2 = %d\n" , * * ptr2) ;
printf ( "***ptr3 = %d\n" , * * * ptr3) ;
* * * ptr3 = 100 ;
printf ( "修改后 num = %d\n" , num) ;
char * names[ ] = { "Alice" , "Bob" , "Charlie" } ;
char * * p = names;
printf ( "\n名字列表:\n" ) ;
for ( int i = 0 ; i < 3 ; i++ ) {
printf ( "%s\n" , * ( p + i) ) ;
}
return 0 ;
}
8.6 函数指针
# include <stdio.h>
int add ( int a, int b) {
return a + b;
}
int subtract ( int a, int b) {
return a - b;
}
int multiply ( int a, int b) {
return a * b;
}
int calculate ( int a, int b, int ( * operation) ( int , int ) ) {
return operation ( a, b) ;
}
int main ( ) {
int ( * func_ptr) ( int , int ) ;
func_ptr = add;
printf ( "10 + 5 = %d\n" , func_ptr ( 10 , 5 ) ) ;
func_ptr = subtract;
printf ( "10 - 5 = %d\n" , func_ptr ( 10 , 5 ) ) ;
int ( * operations[ ] ) ( int , int ) = { add, subtract, multiply} ;
char * symbols[ ] = { "+" , "-" , "*" } ;
for ( int i = 0 ; i < 3 ; i++ ) {
printf ( "10 %s 5 = %d\n" , symbols[ i] , operations[ i] ( 10 , 5 ) ) ;
}
printf ( "\n使用calculate函数:\n" ) ;
printf ( "10 + 5 = %d\n" , calculate ( 10 , 5 , add) ) ;
printf ( "10 * 5 = %d\n" , calculate ( 10 , 5 , multiply) ) ;
return 0 ;
}
九、结构体与联合体
9.1 结构体基础
# include <stdio.h>
# include <string.h>
struct Student {
int id;
char name[ 50 ] ;
int age;
float score;
} ;
typedef struct {
int x;
int y;
} Point;
int main ( ) {
struct Student s1 = { 1 , "Alice" , 20 , 95.5 } ;
struct Student s2;
s2. id = 2 ;
strcpy ( s2. name, "Bob" ) ;
s2. age = 21 ;
s2. score = 88.0 ;
printf ( "学生1: ID=%d, 姓名=%s, 年龄=%d, 成绩=%.1f\n" ,
s1. id, s1. name, s1. age, s1. score) ;
Point p1 = { 10 , 20 } ;
Point p2 = { 30 , 40 } ;
printf ( "点1: (%d, %d)\n" , p1. x, p1. y) ;
printf ( "点2: (%d, %d)\n" , p2. x, p2. y) ;
struct Student students[ 3 ] = {
{ 1 , "Alice" , 20 , 95.5 } ,
{ 2 , "Bob" , 21 , 88.0 } ,
{ 3 , "Charlie" , 19 , 92.3 }
} ;
printf ( "\n学生列表:\n" ) ;
for ( int i = 0 ; i < 3 ; i++ ) {
printf ( "%d. %s - %.1f分\n" ,
students[ i] . id, students[ i] . name, students[ i] . score) ;
}
return 0 ;
}
9.2 结构体指针
# include <stdio.h>
# include <string.h>
# include <stdlib.h>
typedef struct {
int id;
char name[ 50 ] ;
float salary;
} Employee;
void printEmployee ( Employee * emp) {
printf ( "ID: %d, 姓名: %s, 工资: %.2f\n" ,
emp-> id, emp-> name, emp-> salary) ;
}
Employee* createEmployee ( int id, const char * name, float salary) {
Employee * emp = ( Employee* ) malloc ( sizeof ( Employee) ) ;
if ( emp == NULL ) {
return NULL ;
}
emp-> id = id;
strcpy ( emp-> name, name) ;
emp-> salary = salary;
return emp;
}
int main ( ) {
Employee e1 = { 1 , "Alice" , 50000.0 } ;
Employee * ptr = & e1;
printf ( "方式1: %s\n" , ( * ptr) . name) ;
printf ( "方式2: %s\n" , ptr-> name) ;
Employee * e2 = createEmployee ( 2 , "Bob" , 60000.0 ) ;
if ( e2 != NULL ) {
printEmployee ( e2) ;
free ( e2) ;
}
return 0 ;
}
9.3 嵌套结构体
# include <stdio.h>
# include <string.h>
typedef struct {
int year;
int month;
int day;
} Date;
typedef struct {
char street[ 100 ] ;
char city[ 50 ] ;
char country[ 50 ] ;
} Address;
typedef struct {
char name[ 50 ] ;
Date birthday;
Address address;
} Person;
int main ( ) {
Person p = {
"Alice" ,
{ 1995 , 5 , 15 } ,
{ "123 Main St" , "New York" , "USA" }
} ;
printf ( "姓名: %s\n" , p. name) ;
printf ( "生日: %d-%02d-%02d\n" ,
p. birthday. year, p. birthday. month, p. birthday. day) ;
printf ( "地址: %s, %s, %s\n" ,
p. address. street, p. address. city, p. address. country) ;
return 0 ;
}
9.4 联合体
# include <stdio.h>
union Data {
int i;
float f;
char str[ 20 ] ;
} ;
int main ( ) {
union Data data;
printf ( "联合体大小: %zu bytes\n" , sizeof ( data) ) ;
data. i = 10 ;
printf ( "data.i = %d\n" , data. i) ;
data. f = 3.14 ;
printf ( "data.f = %.2f\n" , data. f) ;
printf ( "data.i = %d(已被覆盖)\n" , data. i) ;
snprintf ( data. str, sizeof ( data. str) , "Hello" ) ;
printf ( "data.str = %s\n" , data. str) ;
return 0 ;
}
9.5 枚举类型
# include <stdio.h>
enum Weekday {
MONDAY,
TUESDAY,
WEDNESDAY,
THURSDAY,
FRIDAY,
SATURDAY,
SUNDAY
} ;
enum Color {
RED = 1 ,
GREEN = 2 ,
BLUE = 4 ,
YELLOW = 8
} ;
int main ( ) {
enum Weekday today = WEDNESDAY;
switch ( today) {
case MONDAY:
printf ( "星期一\n" ) ;
break ;
case WEDNESDAY:
printf ( "星期三\n" ) ;
break ;
default :
printf ( "其他日期\n" ) ;
}
enum Color myColor = RED | BLUE;
if ( myColor & RED) {
printf ( "包含红色\n" ) ;
}
if ( myColor & BLUE) {
printf ( "包含蓝色\n" ) ;
}
return 0 ;
}
十、文件操作
10.1 文件基础
# include <stdio.h>
int main ( ) {
FILE * fp;
fp = fopen ( "test.txt" , "w" ) ;
if ( fp == NULL ) {
printf ( "无法打开文件\n" ) ;
return 1 ;
}
fprintf ( fp, "Hello, World!\n" ) ;
fprintf ( fp, "这是第二行\n" ) ;
fprintf ( fp, "数字: %d\n" , 42 ) ;
fclose ( fp) ;
printf ( "文件写入成功\n" ) ;
fp = fopen ( "test.txt" , "r" ) ;
if ( fp == NULL ) {
printf ( "无法打开文件\n" ) ;
return 1 ;
}
char buffer[ 100 ] ;
printf ( "\n文件内容:\n" ) ;
while ( fgets ( buffer, sizeof ( buffer) , fp) != NULL ) {
printf ( "%s" , buffer) ;
}
fclose ( fp) ;
return 0 ;
}
10.2 文件模式
模式 说明 "r"只读,文件必须存在 "w"只写,文件不存在则创建,存在则清空 "a"追加,文件不存在则创建 "r+"读写,文件必须存在 "w+"读写,文件不存在则创建,存在则清空 "a+"读写,追加模式 "rb" "wb"二进制模式
10.3 字符和字符串IO
# include <stdio.h>
int main ( ) {
FILE * fp;
fp = fopen ( "chars.txt" , "w" ) ;
fputc ( 'A' , fp) ;
fputc ( 'B' , fp) ;
fputc ( 'C' , fp) ;
fclose ( fp) ;
fp = fopen ( "chars.txt" , "r" ) ;
int ch;
while ( ( ch = fgetc ( fp) ) != EOF ) {
printf ( "%c " , ch) ;
}
printf ( "\n" ) ;
fclose ( fp) ;
fp = fopen ( "strings.txt" , "w" ) ;
fputs ( "第一行\n" , fp) ;
fputs ( "第二行\n" , fp) ;
fclose ( fp) ;
fp = fopen ( "strings.txt" , "r" ) ;
char buffer[ 100 ] ;
while ( fgets ( buffer, sizeof ( buffer) , fp) != NULL ) {
printf ( "%s" , buffer) ;
}
fclose ( fp) ;
return 0 ;
}
10.4 格式化IO
# include <stdio.h>
typedef struct {
int id;
char name[ 50 ] ;
float score;
} Student;
int main ( ) {
FILE * fp;
Student students[ ] = {
{ 1 , "Alice" , 95.5 } ,
{ 2 , "Bob" , 88.0 } ,
{ 3 , "Charlie" , 92.3 }
} ;
fp = fopen ( "students.txt" , "w" ) ;
for ( int i = 0 ; i < 3 ; i++ ) {
fprintf ( fp, "%d %s %.1f\n" ,
students[ i] . id, students[ i] . name, students[ i] . score) ;
}
fclose ( fp) ;
fp = fopen ( "students.txt" , "r" ) ;
Student s;
printf ( "学生列表:\n" ) ;
while ( fscanf ( fp, "%d %s %f" , & s. id, s. name, & s. score) == 3 ) {
printf ( "ID: %d, 姓名: %s, 成绩: %.1f\n" ,
s. id, s. name, s. score) ;
}
fclose ( fp) ;
return 0 ;
}
10.5 二进制文件
# include <stdio.h>
# include <string.h>
typedef struct {
int id;
char name[ 50 ] ;
float salary;
} Employee;
int main ( ) {
FILE * fp;
Employee employees[ ] = {
{ 1 , "Alice" , 50000.0 } ,
{ 2 , "Bob" , 60000.0 } ,
{ 3 , "Charlie" , 55000.0 }
} ;
fp = fopen ( "employees.dat" , "wb" ) ;
fwrite ( employees, sizeof ( Employee) , 3 , fp) ;
fclose ( fp) ;
printf ( "二进制文件写入成功\n" ) ;
fp = fopen ( "employees.dat" , "rb" ) ;
Employee emp;
printf ( "\n员工列表:\n" ) ;
while ( fread ( & emp, sizeof ( Employee) , 1 , fp) == 1 ) {
printf ( "ID: %d, 姓名: %s, 工资: %.2f\n" ,
emp. id, emp. name, emp. salary) ;
}
fclose ( fp) ;
return 0 ;
}
10.6 文件定位
# include <stdio.h>
int main ( ) {
FILE * fp = fopen ( "test.txt" , "w+" ) ;
fprintf ( fp, "0123456789" ) ;
rewind ( fp) ;
printf ( "当前位置: %ld\n" , ftell ( fp) ) ;
fseek ( fp, 5 , SEEK_SET ) ;
printf ( "当前位置: %ld\n" , ftell ( fp) ) ;
int ch = fgetc ( fp) ;
printf ( "读取字符: %c\n" , ch) ;
fseek ( fp, 0 , SEEK_END ) ;
printf ( "文件大小: %ld bytes\n" , ftell ( fp) ) ;
fclose ( fp) ;
return 0 ;
}
十一、动态内存管理
11.1 malloc和free
# include <stdio.h>
# include <stdlib.h>
int main ( ) {
int * ptr = ( int * ) malloc ( sizeof ( int ) ) ;
if ( ptr == NULL ) {
printf ( "内存分配失败\n" ) ;
return 1 ;
}
* ptr = 42 ;
printf ( "值: %d\n" , * ptr) ;
free ( ptr) ;
int n = 5 ;
int * arr = ( int * ) malloc ( n * sizeof ( int ) ) ;
if ( arr == NULL ) {
printf ( "内存分配失败\n" ) ;
return 1 ;
}
for ( int i = 0 ; i < n; i++ ) {
arr[ i] = i * 10 ;
}
printf ( "数组: " ) ;
for ( int i = 0 ; i < n; i++ ) {
printf ( "%d " , arr[ i] ) ;
}
printf ( "\n" ) ;
free ( arr) ;
return 0 ;
}
11.2 calloc和realloc
# include <stdio.h>
# include <stdlib.h>
int main ( ) {
int * arr1 = ( int * ) calloc ( 5 , sizeof ( int ) ) ;
printf ( "calloc分配的数组: " ) ;
for ( int i = 0 ; i < 5 ; i++ ) {
printf ( "%d " , arr1[ i] ) ;
}
printf ( "\n" ) ;
arr1 = ( int * ) realloc ( arr1, 10 * sizeof ( int ) ) ;
if ( arr1 == NULL ) {
printf ( "重新分配失败\n" ) ;
return 1 ;
}
for ( int i = 5 ; i < 10 ; i++ ) {
arr1[ i] = i;
}
printf ( "扩展后的数组: " ) ;
for ( int i = 0 ; i < 10 ; i++ ) {
printf ( "%d " , arr1[ i] ) ;
}
printf ( "\n" ) ;
free ( arr1) ;
return 0 ;
}
11.3 动态二维数组
# include <stdio.h>
# include <stdlib.h>
int main ( ) {
int rows = 3 , cols = 4 ;
int * * matrix = ( int * * ) malloc ( rows * sizeof ( int * ) ) ;
for ( int i = 0 ; i < rows; i++ ) {
matrix[ i] = ( int * ) malloc ( cols * sizeof ( int ) ) ;
}
for ( int i = 0 ; i < rows; i++ ) {
for ( int j = 0 ; j < cols; j++ ) {
matrix[ i] [ j] = i * cols + j;
}
}
printf ( "矩阵:\n" ) ;
for ( int i = 0 ; i < rows; i++ ) {
for ( int j = 0 ; j < cols; j++ ) {
printf ( "%3d " , matrix[ i] [ j] ) ;
}
printf ( "\n" ) ;
}
for ( int i = 0 ; i < rows; i++ ) {
free ( matrix[ i] ) ;
}
free ( matrix) ;
return 0 ;
}
11.4 内存泄漏检测
# include <stdio.h>
# include <stdlib.h>
void memory_leak ( ) {
int * ptr = ( int * ) malloc ( sizeof ( int ) ) ;
* ptr = 42 ;
}
void proper_management ( ) {
int * ptr = ( int * ) malloc ( sizeof ( int ) ) ;
if ( ptr == NULL ) {
return ;
}
* ptr = 42 ;
printf ( "值: %d\n" , * ptr) ;
free ( ptr) ;
ptr = NULL ;
}
int main ( ) {
proper_management ( ) ;
return 0 ;
}
十二、预处理器
12.1 宏定义
# include <stdio.h>
# define PI 3.14159
# define MAX_SIZE 100
# define SQUARE ( x) ( ( x) * ( x) )
# define MAX ( a, b) ( ( a) > ( b) ? ( a) : ( b) )
# define MIN ( a, b) ( ( a) < ( b) ? ( a) : ( b) )
# define PRINT_ARRAY ( arr, size) \
do { \
for ( int i = 0 ; i < ( size) ; i++ ) { \
printf ( "%d " , ( arr) [ i] ) ; \
} \
printf ( "\n" ) ; \
} while ( 0 )
int main ( ) {
printf ( "圆周率: %f\n" , PI) ;
printf ( "最大容量: %d\n" , MAX_SIZE) ;
printf ( "5的平方: %d\n" , SQUARE ( 5 ) ) ;
printf ( "最大值: %d\n" , MAX ( 10 , 20 ) ) ;
int arr[ ] = { 1 , 2 , 3 , 4 , 5 } ;
printf ( "数组: " ) ;
PRINT_ARRAY ( arr, 5 ) ;
return 0 ;
}
12.2 条件编译
# include <stdio.h>
# define DEBUG 1
# define VERSION 2
int main ( ) {
# ifdef DEBUG
printf ( "调试模式开启\n" ) ;
# endif
# ifndef RELEASE
printf ( "非发布版本\n" ) ;
# endif
# if VERSION == 1
printf ( "版本 1\n" ) ;
# elif VERSION == 2
printf ( "版本 2\n" ) ;
# else
printf ( "未知版本\n" ) ;
# endif
printf ( "文件: %s\n" , __FILE__ ) ;
printf ( "行号: %d\n" , __LINE__ ) ;
printf ( "日期: %s\n" , __DATE__ ) ;
printf ( "时间: %s\n" , __TIME__ ) ;
return 0 ;
}
12.3 文件包含
# ifndef MATH_UTILS_H
# define MATH_UTILS_H
int add ( int a, int b) ;
int multiply ( int a, int b) ;
# endif
# include "math_utils.h"
int add ( int a, int b) {
return a + b;
}
int multiply ( int a, int b) {
return a * b;
}
# include <stdio.h>
# include "math_utils.h"
int main ( ) {
printf ( "10 + 5 = %d\n" , add ( 10 , 5 ) ) ;
printf ( "10 * 5 = %d\n" , multiply ( 10 , 5 ) ) ;
return 0 ;
}
十三、实战项目
13.1 项目1: 学生管理系统
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
# define MAX_STUDENTS 100
# define NAME_LENGTH 50
typedef struct {
int id;
char name[ NAME_LENGTH] ;
int age;
float score;
} Student;
Student students[ MAX_STUDENTS] ;
int student_count = 0 ;
void addStudent ( ) {
if ( student_count >= MAX_STUDENTS) {
printf ( "学生数量已达上限\n" ) ;
return ;
}
Student * s = & students[ student_count] ;
printf ( "输入学号: " ) ;
scanf ( "%d" , & s-> id) ;
printf ( "输入姓名: " ) ;
scanf ( "%s" , s-> name) ;
printf ( "输入年龄: " ) ;
scanf ( "%d" , & s-> age) ;
printf ( "输入成绩: " ) ;
scanf ( "%f" , & s-> score) ;
student_count++ ;
printf ( "添加成功!\n" ) ;
}
void displayStudents ( ) {
if ( student_count == 0 ) {
printf ( "暂无学生记录\n" ) ;
return ;
}
printf ( "\n%-10s %-20s %-10s %-10s\n" , "学号" , "姓名" , "年龄" , "成绩" ) ;
printf ( "----------------------------------------------------------\n" ) ;
for ( int i = 0 ; i < student_count; i++ ) {
printf ( "%-10d %-20s %-10d %-10.1f\n" ,
students[ i] . id,
students[ i] . name,
students[ i] . age,
students[ i] . score) ;
}
}
void searchStudent ( ) {
int id;
printf ( "输入要查找的学号: " ) ;
scanf ( "%d" , & id) ;
for ( int i = 0 ; i < student_count; i++ ) {
if ( students[ i] . id == id) {
printf ( "\n找到学生:\n" ) ;
printf ( "学号: %d\n" , students[ i] . id) ;
printf ( "姓名: %s\n" , students[ i] . name) ;
printf ( "年龄: %d\n" , students[ i] . age) ;
printf ( "成绩: %.1f\n" , students[ i] . score) ;
return ;
}
}
printf ( "未找到该学生\n" ) ;
}
void deleteStudent ( ) {
int id;
printf ( "输入要删除的学号: " ) ;
scanf ( "%d" , & id) ;
for ( int i = 0 ; i < student_count; i++ ) {
if ( students[ i] . id == id) {
for ( int j = i; j < student_count - 1 ; j++ ) {
students[ j] = students[ j + 1 ] ;
}
student_count-- ;
printf ( "删除成功!\n" ) ;
return ;
}
}
printf ( "未找到该学生\n" ) ;
}
void saveToFile ( ) {
FILE * fp = fopen ( "students.dat" , "wb" ) ;
if ( fp == NULL ) {
printf ( "无法打开文件\n" ) ;
return ;
}
fwrite ( & student_count, sizeof ( int ) , 1 , fp) ;
fwrite ( students, sizeof ( Student) , student_count, fp) ;
fclose ( fp) ;
printf ( "保存成功!\n" ) ;
}
void loadFromFile ( ) {
FILE * fp = fopen ( "students.dat" , "rb" ) ;
if ( fp == NULL ) {
printf ( "文件不存在\n" ) ;
return ;
}
fread ( & student_count, sizeof ( int ) , 1 , fp) ;
fread ( students, sizeof ( Student) , student_count, fp) ;
fclose ( fp) ;
printf ( "加载成功! 共%d条记录\n" , student_count) ;
}
int main ( ) {
int choice;
loadFromFile ( ) ;
while ( 1 ) {
printf ( "\n========== 学生管理系统 ==========\n" ) ;
printf ( "1. 添加学生\n" ) ;
printf ( "2. 显示所有学生\n" ) ;
printf ( "3. 查找学生\n" ) ;
printf ( "4. 删除学生\n" ) ;
printf ( "5. 保存数据\n" ) ;
printf ( "6. 退出\n" ) ;
printf ( "==================================\n" ) ;
printf ( "请选择: " ) ;
scanf ( "%d" , & choice) ;
switch ( choice) {
case 1 :
addStudent ( ) ;
break ;
case 2 :
displayStudents ( ) ;
break ;
case 3 :
searchStudent ( ) ;
break ;
case 4 :
deleteStudent ( ) ;
break ;
case 5 :
saveToFile ( ) ;
break ;
case 6 :
saveToFile ( ) ;
printf ( "再见!\n" ) ;
return 0 ;
default :
printf ( "无效选择!\n" ) ;
}
}
return 0 ;
}
13.2 项目2: 简易计算器
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
# include <math.h>
double add ( double a, double b) { return a + b; }
double subtract ( double a, double b) { return a - b; }
double multiply ( double a, double b) { return a * b; }
double divide ( double a, double b) {
if ( b == 0 ) {
printf ( "错误: 除数不能为0\n" ) ;
return 0 ;
}
return a / b;
}
double power ( double base, double exp) { return pow ( base, exp) ; }
double squareRoot ( double num) {
if ( num < 0 ) {
printf ( "错误: 不能对负数开方\n" ) ;
return 0 ;
}
return sqrt ( num) ;
}
void showMenu ( ) {
printf ( "\n========== 简易计算器 ==========\n" ) ;
printf ( "1. 加法 (+)\n" ) ;
printf ( "2. 减法 (-)\n" ) ;
printf ( "3. 乘法 (*)\n" ) ;
printf ( "4. 除法 (/)\n" ) ;
printf ( "5. 幂运算 (^)\n" ) ;
printf ( "6. 平方根 (√)\n" ) ;
printf ( "7. 退出\n" ) ;
printf ( "==================================\n" ) ;
}
int main ( ) {
int choice;
double num1, num2, result;
while ( 1 ) {
showMenu ( ) ;
printf ( "请选择操作: " ) ;
scanf ( "%d" , & choice) ;
if ( choice == 7 ) {
printf ( "感谢使用!\n" ) ;
break ;
}
if ( choice == 6 ) {
printf ( "输入数字: " ) ;
scanf ( "%lf" , & num1) ;
result = squareRoot ( num1) ;
printf ( "√%.2f = %.2f\n" , num1, result) ;
continue ;
}
if ( choice >= 1 && choice <= 5 ) {
printf ( "输入第一个数: " ) ;
scanf ( "%lf" , & num1) ;
printf ( "输入第二个数: " ) ;
scanf ( "%lf" , & num2) ;
switch ( choice) {
case 1 :
result = add ( num1, num2) ;
printf ( "%.2f + %.2f = %.2f\n" , num1, num2, result) ;
break ;
case 2 :
result = subtract ( num1, num2) ;
printf ( "%.2f - %.2f = %.2f\n" , num1, num2, result) ;
break ;
case 3 :
result = multiply ( num1, num2) ;
printf ( "%.2f * %.2f = %.2f\n" , num1, num2, result) ;
break ;
case 4 :
result = divide ( num1, num2) ;
printf ( "%.2f / %.2f = %.2f\n" , num1, num2, result) ;
break ;
case 5 :
result = power ( num1, num2) ;
printf ( "%.2f ^ %.2f = %.2f\n" , num1, num2, result) ;
break ;
}
} else {
printf ( "无效选择!\n" ) ;
}
}
return 0 ;
}
13.3 项目3: 链表实现
# include <stdio.h>
# include <stdlib.h>
typedef struct Node {
int data;
struct Node * next;
} Node;
Node* createNode ( int data) {
Node * newNode = ( Node* ) malloc ( sizeof ( Node) ) ;
newNode-> data = data;
newNode-> next = NULL ;
return newNode;
}
void insertAtHead ( Node * * head, int data) {
Node * newNode = createNode ( data) ;
newNode-> next = * head;
* head = newNode;
}
void insertAtTail ( Node * * head, int data) {
Node * newNode = createNode ( data) ;
if ( * head == NULL ) {
* head = newNode;
return ;
}
Node * current = * head;
while ( current-> next != NULL ) {
current = current-> next;
}
current-> next = newNode;
}
void deleteNode ( Node * * head, int data) {
if ( * head == NULL ) return ;
if ( ( * head) -> data == data) {
Node * temp = * head;
* head = ( * head) -> next;
free ( temp) ;
return ;
}
Node * current = * head;
while ( current-> next != NULL ) {
if ( current-> next-> data == data) {
Node * temp = current-> next;
current-> next = current-> next-> next;
free ( temp) ;
return ;
}
current = current-> next;
}
}
Node* search ( Node * head, int data) {
Node * current = head;
while ( current != NULL ) {
if ( current-> data == data) {
return current;
}
current = current-> next;
}
return NULL ;
}
void printList ( Node * head) {
if ( head == NULL ) {
printf ( "链表为空\n" ) ;
return ;
}
Node * current = head;
while ( current != NULL ) {
printf ( "%d -> " , current-> data) ;
current = current-> next;
}
printf ( "NULL\n" ) ;
}
int getLength ( Node * head) {
int length = 0 ;
Node * current = head;
while ( current != NULL ) {
length++ ;
current = current-> next;
}
return length;
}
void freeList ( Node * * head) {
Node * current = * head;
while ( current != NULL ) {
Node * temp = current;
current = current-> next;
free ( temp) ;
}
* head = NULL ;
}
int main ( ) {
Node * head = NULL ;
insertAtHead ( & head, 10 ) ;
insertAtHead ( & head, 20 ) ;
insertAtTail ( & head, 30 ) ;
insertAtTail ( & head, 40 ) ;
printf ( "链表: " ) ;
printList ( head) ;
printf ( "长度: %d\n" , getLength ( head) ) ;
int searchData = 30 ;
Node * found = search ( head, searchData) ;
if ( found) {
printf ( "找到元素: %d\n" , searchData) ;
} else {
printf ( "未找到元素: %d\n" , searchData) ;
}
deleteNode ( & head, 20 ) ;
printf ( "删除20后: " ) ;
printList ( head) ;
freeList ( & head) ;
return 0 ;
}
附录
A. C语言学习路径
系统编程
数据结构
嵌入式
开始学习C语言
环境搭建
基础语法
数据类型与运算符
控制流程
函数
数组与字符串
指针
选择方向
文件操作
链表/树/图
单片机编程
项目实战
B. 常见错误与调试
错误类型 原因 解决方法 段错误 访问非法内存 检查指针、数组越界 内存泄漏 忘记free 配对malloc/free 野指针 使用未初始化指针 初始化为NULL 缓冲区溢出 字符串操作越界 使用strncpy等安全函数
C. 编译选项
gcc program.c -o program
gcc -Wall -Wextra program.c -o program
gcc -g program.c -o program
gcc -O2 program.c -o program
gcc program.c -o program -lm
gcc main.c utils.c -o program
文档版本 : v1.0 编制日期 : 2025年10月 适用人群 : C语言初学者到中级开发者 预计学习时间 : 8-12周
祝学习愉快!💻✨