为了方便学习和查阅,我将它们分为了几个大类,并为每个程序提供了题目描述、核心思路和代码示例。

(图片来源网络,侵删)
第一部分:基础入门 (1-20)
这个部分主要帮助初学者掌握C语言的基本语法、流程控制、函数和数组。
-
Hello, World!
- 描述:程序员的第一个程序,在屏幕上打印 "Hello, World!"。
- 核心思路:使用
printf函数输出字符串。 - 代码:
#include <stdio.h> int main() { printf("Hello, World!\n"); return 0; }
-
两数相加
- 描述:从用户输入获取两个整数,计算并输出它们的和。
- 核心思路:使用
scanf读取用户输入, 运算符进行加法。 - 代码:
#include <stdio.h> int main() { int a, b, sum; printf("Enter two integers: "); scanf("%d %d", &a, &b); sum = a + b; printf("Sum: %d\n", sum); return 0; }
-
判断奇偶数
- 描述:输入一个整数,判断它是奇数还是偶数。
- 核心思路:使用模运算 ,
num % 2 == 0则为偶数,否则为奇数。 - 代码:
#include <stdio.h> int main() { int num; printf("Enter an integer: "); scanf("%d", &num); if(num % 2 == 0) printf("%d is even.\n", num); else printf("%d is odd.\n", num); return 0; }
-
大小写字母转换
- 描述:将输入的小写字母转换为大写字母,反之亦然。
- 核心思路:利用ASCII码值差。
'a' - 'A'是32。char可以直接进行算术运算。 - 代码:
#include <stdio.h> int main() { char c; printf("Enter a character: "); scanf("%c", &c); if(c >= 'a' && c <= 'z') printf("Uppercase: %c\n", c - 'a' + 'A'); else if(c >= 'A' && c <= 'Z') printf("Lowercase: %c\n", c - 'A' + 'a'); return 0; }
-
求阶乘
- 描述:计算一个非负整数的阶乘 (n!)。
- 核心思路:使用循环(for或while)从1乘到n。
- 代码:
#include <stdio.h> int main() { int n, i, fact = 1; printf("Enter a positive integer: "); scanf("%d", &n); for(i = 1; i <= n; ++i) fact *= i; printf("Factorial of %d = %d\n", n, fact); return 0; }
-
判断素数
- 描述:判断一个输入的整数是否为素数(质数)。
- 核心思路:素数是只能被1和它本身整除的数,只需检查从2到
sqrt(n)之间是否有能整除n的数。 - 代码:
#include <stdio.h> #include <math.h> int main() { int n, i, flag = 0; printf("Enter a positive integer: "); scanf("%d", &n); for(i = 2; i <= sqrt(n); ++i) { if(n % i == 0) { flag = 1; break; } } if (n == 1) printf("1 is neither prime nor composite.\n"); else if (flag == 0) printf("%d is a prime number.\n", n); else printf("%d is not a prime number.\n", n); return 0; }
-
打印斐波那契数列
- 描述:打印前n项斐波那契数列(1, 1, 2, 3, 5, 8...)。
- 核心思路:使用循环,每次迭代计算下一个数,前两个数之和等于下一个数。
- 代码:
#include <stdio.h> int main() { int n, t1 = 0, t2 = 1, nextTerm; printf("Enter the number of terms: "); scanf("%d", &n); printf("Fibonacci Series: "); for (i = 1; i <= n; ++i) { printf("%d, ", t1); nextTerm = t1 + t2; t1 = t2; t2 = nextTerm; } return 0; }
-
使用递归求阶乘
- 描述:用递归函数实现阶乘计算。
- 核心思路:递归函数调用自身。
factorial(n) = n * factorial(n-1),终止条件为n == 0。 - 代码:
#include <stdio.h> long factorial(int n) { if (n >= 1) return n * factorial(n - 1); else return 1; } int main() { int n; printf("Enter a positive integer: "); scanf("%d", &n); printf("Factorial of %d = %ld\n", n, factorial(n)); return 0; }
-
打印九九乘法表
- 描述:打印标准的九九乘法表。
- 核心思路:使用嵌套的for循环,外层循环控制行,内层循环控制列。
- 代码:
#include <stdio.h> int main() { int i, j; for(i = 1; i <= 9; i++) { for(j = 1; j <= i; j++) { printf("%d*%d=%-3d ", i, j, i*j); } printf("\n"); } return 0; }
-
交换两个变量
- 描述:交换两个变量的值。
- 核心思路:可以使用临时变量,也可以使用算术运算或异或运算实现无临时变量交换。
- 代码 (临时变量法):
#include <stdio.h> int main() { int a = 5, b = 10, temp; printf("Before swap: a = %d, b = %d\n", a, b); temp = a; a = b; b = temp; printf("After swap: a = %d, b = %d\n", a, b); return 0; }
-
找出数组中的最大/最小值
- 描述:在给定的整数数组中找出最大值和最小值。
- 核心思路:假设第一个元素为最大/最小值,然后遍历数组进行比较更新。
- 代码:
#include <stdio.h> int main() { int arr[] = {10, 20, 5, 30, 15}; int n = sizeof(arr) / sizeof(arr[0]); int max = arr[0], min = arr[0]; for(int i = 1; i < n; i++) { if(arr[i] > max) max = arr[i]; if(arr[i] < min) min = arr[i]; } printf("Max: %d, Min: %d\n", max, min); return 0; }
-
数组元素逆序
- 描述:将数组中的元素顺序反转。
- 核心思路:使用双指针,一个从头部开始,一个从尾部开始,交换它们指向的元素,直到指针相遇。
- 代码:
#include <stdio.h> int main() { int arr[] = {1, 2, 3, 4, 5}; int n = sizeof(arr) / sizeof(arr[0]); for(int i = 0; i < n/2; i++) { int temp = arr[i]; arr[i] = arr[n - 1 - i]; arr[n - 1 - i] = temp; } for(int i = 0; i < n; i++) { printf("%d ", arr[i]); } return 0; }
-
简单计算器
- 描述:根据用户输入的两个数字和运算符,进行加减乘除运算。
- 核心思路:使用
switch-case语句根据不同的运算符执行相应的计算。 - 代码:
#include <stdio.h> int main() { char op; double a, b; printf("Enter an operator (+, -, *, /): "); scanf("%c", &op); printf("Enter two operands: "); scanf("%lf %lf", &a, &b); switch(op) { case '+': printf("%.1lf + %.1lf = %.1lf\n", a, b, a + b); break; case '-': printf("%.1lf - %.1lf = %.1lf\n", a, b, a - b); break; case '*': printf("%.1lf * %.1lf = %.1lf\n", a, b, a * b); break; case '/': if(b != 0) printf("%.1lf / %.1lf = %.1lf\n", a, b, a / b); else printf("Division by zero!\n"); break; default: printf("Invalid operator!\n"); } return 0; }
-
打印杨辉三角
- 描述:打印指定行数的杨辉三角。
- 核心思路:使用二维数组,每个位置的值等于它上方和左上方两个数的和。
- 代码:
#include <stdio.h> int main() { int rows, coef = 1, space, i, j; printf("Enter number of rows: "); scanf("%d", &rows); for(i = 0; i < rows; i++) { for(space = 1; space <= rows - i; space++) printf(" "); for(j = 0; j <= i; j++) { if (j == 0 || i == 0) coef = 1; else coef = coef * (i - j + 1) / j; printf("%4d", coef); } printf("\n"); } return 0; }
-
字符串长度(不使用库函数)
- 描述:计算一个字符串的长度,不能使用
strlen。 - 核心思路:使用循环遍历字符串,直到遇到
\0(空字符)为止。 - 代码:
#include <stdio.h> int main() { char str[100]; int length = 0; printf("Enter a string: "); gets(str); // 注意: gets()不安全,仅作示例 while(str[length] != '\0') length++; printf("Length: %d\n", length); return 0; }
- 描述:计算一个字符串的长度,不能使用
-
字符串反转
- 描述:将输入的字符串反转。
- 核心思路:与数组逆序类似,使用双指针交换字符。
- 代码:
#include <stdio.h> #include <string.h> void reverseString(char str[]) { int n = strlen(str); for(int i = 0; i < n/2; i++) { char temp = str[i]; str[i] = str[n - 1 - i]; str[n - 1 - i] = temp; } } int main() { str[100]; printf("Enter a string: "); gets(str); reverseString(str); printf("Reversed string: %s\n", str); return 0; }
-
合并两个有序数组
- 描述:将两个已经排好序的数组合并成一个有序数组。
- 核心思路:使用双指针,分别指向两个数组的开头,比较元素大小,将较小的放入新数组,然后移动指针。
- 代码:
#include <stdio.h> int main() { int a[] = {1, 3, 5}, b[] = {2, 4, 6}; int n1 = sizeof(a)/sizeof(a[0]), n2 = sizeof(b)/sizeof(b[0]); int merged[n1+n2]; int i = 0, j = 0, k = 0; while(i < n1 && j < n2) { if(a[i] < b[j]) merged[k++] = a[i++]; else merged[k++] = b[j++]; } while(i < n1) merged[k++] = a[i++]; while(j < n2) merged[k++] = b[j++]; for(i = 0; i < n1+n2; i++) printf("%d ", merged[i]); return 0; }
-
冒泡排序
- 描述:使用冒泡排序算法对数组进行排序。
- 核心思路: repeatedly steps through the list, compares adjacent elements and swaps them if they are in the wrong order.
- 代码:
#include <stdio.h> int main() { int arr[] = {64, 34, 25, 12, 22, 11, 90}; int n = sizeof(arr)/sizeof(arr[0]); for(int i = 0; i < n-1; i++) { for(int j = 0; j < n-i-1; j++) { if(arr[j] > arr[j+1]) { int temp = arr[j]; arr[j] = arr[j+1]; arr[j+1] = temp; } } } for(int i = 0; i < n; i++) printf("%d ", arr[i]); return 0; }
-
选择排序
- 描述:使用选择排序算法对数组进行排序。
- 核心思路:每次从未排序部分找到最小(或最大)的元素,放到已排序部分的末尾。
- 代码:
#include <stdio.h> int main() { int arr[] = {64, 25, 12, 22, 11}; int n = sizeof(arr)/sizeof(arr[0]); for(int i = 0; i < n-1; i++) { int min_idx = i; for(int j = i+1; j < n; j++) { if(arr[j] < arr[min_idx]) min_idx = j; } int temp = arr[min_idx]; arr[min_idx] = arr[i]; arr[i] = temp; } for(int i = 0; i < n; i++) printf("%d ", arr[i]); return 0; }
-
插入排序
- 描述:使用插入排序算法对数组进行排序。
- 核心思路:构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。
- 代码:
#include <stdio.h> int main() { int arr[] = {12, 11, 13, 5, 6}; int n = sizeof(arr)/sizeof(arr[0]); for(int i = 1; i < n; i++) { int key = arr[i]; int j = i - 1; while(j >= 0 && arr[j] > key) { arr[j+1] = arr[j]; j--; } arr[j+1] = key; } for(int i = 0; i < n; i++) printf("%d ", arr[i]); return 0; }
第二部分:数据结构与算法 (21-50)
这个部分深入探讨链表、栈、队列、树、图等数据结构和排序、查找等核心算法。
- 单向链表的基本操作 (创建、插入、删除、遍历)
- 双向链表的基本操作
- 栈的实现(数组版) (Push, Pop, isEmpty)
- 栈的实现(链表版)
- 队列的实现(数组版,循环队列) (Enqueue, Dequeue)
- 队列的实现(链表版)
- 二叉树的遍历 (前序、中序、后序)
- 二叉查找树的实现 (插入、查找、删除)
- 堆排序
- 快速排序
- 归并排序
- 二分查找
- 深度优先搜索 (DFS)
- 广度优先搜索 (BFS)
- 图的邻接矩阵表示
- 图的邻接表表示
- 计算字符串的哈希值(简单版本)
- 实现一个简单的哈希表(链地址法解决冲突)
- 求最大公约数 (GCD) - 辗转相除法
- 求最小公倍数 (LCM)
- 汉诺塔问题(递归解法)
- 判断回文字符串
- 实现一个简单的文本编辑器(命令行版) (如插入、删除、查找)
- 实现一个简单的计算器(支持括号) (使用栈处理表达式)
- 实现一个简单的Shell (循环读取用户命令并执行)
- 约瑟夫环问题
- 实现一个简单的LRU缓存
- 并查集 (Union-Find) 数据结构
- KMP字符串匹配算法
- Dijkstra最短路径算法
第三部分:文件与I/O (51-65)
这个部分重点学习文件操作、命令行参数和标准输入输出。
- 文件写入 (将字符串写入文本文件)
- 文件读取 (从文本文件中读取并显示内容)
- 二进制文件读写 (写入和读取结构体数据)
- 命令行参数处理 (
argc和argv的使用) - 重定向标准输入输出 (使用
freopen) - 文件信息获取 (获取文件大小、创建时间等,使用
stat函数) - 实现
cat命令 (显示文件内容) - 实现
cp命令 (复制文件) - 实现
ls命令 (列出目录内容,简化版) - 逐行读取文件
- 统计文件中的单词数和行数
- 到文件
- 文件加密与解密(简单异或)
- 内存映射文件
- 管道通信 (Pipe) (父子进程间通过管道通信)
第四部分:系统与底层编程 (66-85)
这个部分涉及内存管理、指针进阶、进程和线程等更底层的主题。
- 使用
malloc和free进行动态内存分配 - 使用
calloc和realloc - 实现一个简单的内存分配器(伙伴系统思想)
- 函数指针的使用
- 回调函数的实现
- 使用
qsort函数进行排序 - 使用
bsearch函数进行查找 - 多线程编程 (使用
pthread库) (创建线程、同步) - 使用互斥锁 (
mutex) - 使用信号量 (
semaphore) - 创建子进程 (
fork和exec系列函数) - 进程间通信 (IPC) - 消息队列
- 进程间通信 (IPC) - 共享内存
- 实现一个简单的守护进程
- 信号处理 (
signal函数) - 处理命令行选项 (
getopt函数) - 读取系统环境变量
- 使用
setjmp和longjmp进行非局部跳转 - 实现一个简单的Shell(带管道和后台执行)
- 动态链接库的创建与使用
第五部分:综合应用与项目 (86-100)
这个部分是一些综合性的项目,需要综合运用前面所学的知识。
- 学生成绩管理系统 (增删改查、排序、统计)
- 图书管理系统 (增删改查、借阅、归还)
- 贪吃蛇游戏 (使用控制台,
ncurses库) - 俄罗斯方块游戏
- 简单的HTTP服务器 (能处理GET请求)
- 实现一个简单的FTP客户端
- 实现一个简单的聊天室
- 实现一个简单的键值存储数据库
- 实现一个简单的日志系统
- 实现一个简单的单元测试框架
- 实现一个命令行解析器
- 实现一个简单的Makefile构建系统
- 实现一个简单的解释器 (如计算器语言的解释器)
- 实现一个简单的编译器前端 (词法分析、语法分析)
- 实现一个简单的操作系统内核(引导、中断、任务切换)
学习建议
- 循序渐进:不要急于求成,严格按照从基础到综合的顺序学习。
- 动手实践:对于每个程序,务必亲手敲一遍、编译、运行、修改,并理解其工作原理。
- 调试:学会使用
gdb等调试工具,当程序出错时,单步调试是理解代码执行流程的最好方法。 - 阅读源码:尝试阅读一些开源C语言项目(如
Redis,Nginx的一部分)的源码,看看大师们是如何写代码的。 - 注重基础:指针、内存管理、数据结构是C语言的灵魂,一定要学扎实。
这份列表涵盖了C语言学习的方方面面,希望它能成为你学习路上的一个有力工具,祝你学习愉快!
