C语言经典100例程序教程

C语言经典100例程序教程

说明
本教程按照题目类型划分为 10 个部分,每部分包含 10 个例题,既适合初学者入门,也能帮助进阶者巩固基本算法和数据结构的实现。
编译示例程序时,请使用支持 C99 或更高标准的编译器,例如:

gcc example.c -std=c99 -o example

📑 目录

  1. 基础语法(例 01 ~ 10)
  2. 字符串与数组(例 11 ~ 20)
  3. 排序与搜索算法(例 21 ~ 30)
  4. 数据结构(例 31 ~ 40)
  5. 递归与经典问题(例 41 ~ 50)
  6. 指针与内存管理(例 51 ~ 60)
  7. 文件 I/O 与错误处理(例 61 ~ 70)
  8. 位操作与数值运算(例 71 ~ 80)
  9. 实用算法与综合实例(例 81 ~ 90)
  10. 杂项与拓展练习(例 91 ~ 100)

基础语法(例 01 ~ 10)

例 01 — Hello World

#include <stdio.h>

int main(void) {
    printf("Hello, World!\n");
    return 0;
}

说明:最简单的 C 程序,输出 “Hello, World!”。


例 02 — 交换两个整数(不借助第三变量,利用异或)

#include <stdio.h>

int main(void) {
    int a, b;
    printf("请输入两个整数:");
    scanf("%d %d", &a, &b);
    // 利用异或进行交换
    a = a ^ b;
    b = a ^ b;
    a = a ^ b;
    printf("交换后:a = %d, b = %d\n", a, b);
    return 0;
}

说明:利用异或运算符实现不借助临时变量的交换。


例 03 — 阶乘(递归实现)

#include <stdio.h>

long long factorial(int n) {
    return n <= 1 ? 1 : n * factorial(n - 1);
}

int main(void) {
    int n;
    printf("请输入一个整数:");
    scanf("%d", &n);
    printf("%d 的阶乘是 %lld\n", n, factorial(n));
    return 0;
}

说明:使用递归方式计算阶乘。


例 04 — 斐波那契数列(迭代实现)

#include <stdio.h>

int main(void) {
    int n;
    printf("请输入斐波那契数列项数:");
    scanf("%d", &n);
    
    long long a = 0, b = 1, temp;
    printf("斐波那契数列:\n");
    for (int i = 0; i < n; i++) {
        printf("%lld ", a);
        temp = a + b;
        a = b;
        b = temp;
    }
    printf("\n");
    return 0;
}

说明:利用迭代求斐波那契序列。


例 05 — 判断质数

#include <stdio.h>
#include <math.h>
#include <stdbool.h>

bool isPrime(int n) {
    if(n < 2) return false;
    for (int i = 2; i <= (int)sqrt(n); i++) {
        if (n % i == 0)
            return false;
    }
    return true;
}

int main(void) {
    int n;
    printf("请输入一个整数:");
    scanf("%d", &n);
    printf("%d %s质数。\n", n, isPrime(n) ? "是" : "不是");
    return 0;
}

说明:判断输入的整数是否为质数。


例 06 — 输出指定范围内的所有质数

#include <stdio.h>
#include <math.h>
#include <stdbool.h>

bool isPrime(int n) {
    if(n < 2) return false;
    for (int i = 2; i <= (int)sqrt(n); i++) {
        if (n % i == 0)
            return false;
    }
    return true;
}

int main(void) {
    int lower, upper;
    printf("请输入下界和上界:");
    scanf("%d %d", &lower, &upper);
    printf("区间内的质数有:\n");
    for (int i = lower; i <= upper; i++) {
        if (isPrime(i))
            printf("%d ", i);
    }
    printf("\n");
    return 0;
}

说明:遍历区间,依次判断打印质数。


例 07 — 最大公约数与最小公倍数

#include <stdio.h>

int gcd(int a, int b) {
    return b == 0 ? a : gcd(b, a % b);
}

int main(void) {
    int a, b;
    printf("请输入两个正整数:");
    scanf("%d %d", &a, &b);
    int g = gcd(a, b);
    printf("最大公约数:%d\n", g);
    printf("最小公倍数:%d\n", a / g * b);
    return 0;
}

说明:利用欧几里得算法求 GCD,并计算 LCM。


例 08 — 反转整数

#include <stdio.h>

int main(void) {
    int n, rev = 0;
    printf("请输入一个整数:");
    scanf("%d", &n);
    while(n != 0) {
        rev = rev * 10 + n % 10;
        n /= 10;
    }
    printf("反转后的整数为:%d\n", rev);
    return 0;
}

说明:利用循环求整数反转。


例 09 — 判断回文数

#include <stdio.h>

int main(void) {
    int n, original, rev = 0;
    printf("请输入一个整数:");
    scanf("%d", &n);
    original = n;
    while(n != 0) {
        rev = rev * 10 + n % 10;
        n /= 10;
    }
    if(original == rev)
        printf("是回文数。\n");
    else
        printf("不是回文数。\n");
    return 0;
}

说明:检查输入整数正读和反读是否相同。


例 10 — 判断阿姆斯壮数(三位数)

#include <stdio.h>
#include <math.h>

int main(void) {
    printf("三位阿姆斯壮数有:\n");
    for (int n = 100; n <= 999; n++) {
        int a = n / 100;
        int b = (n / 10) % 10;
        int c = n % 10;
        if (a * a * a + b * b * b + c * c * c == n)
            printf("%d ", n);
    }
    printf("\n");
    return 0;
}

说明:输出所有三位阿姆斯壮数(立方和等于原数)。


字符串与数组(例 11 ~ 20)

例 11 — 求整数各位数字之和

#include <stdio.h>

int main(void) {
    int n, sum = 0;
    printf("请输入一个整数:");
    scanf("%d", &n);
    while(n != 0) {
        sum += n % 10;
        n /= 10;
    }
    printf("各位之和 = %d\n", sum);
    return 0;
}

说明:利用循环将各位数字求和。


例 12 — 十进制转二进制(打印二进制表示)

#include <stdio.h>

void printBinary(unsigned int n) {
    if(n > 1)
        printBinary(n / 2);
    printf("%d", n % 2);
}

int main(void) {
    unsigned int n;
    printf("请输入一个非负整数:");
    scanf("%u", &n);
    printf("二进制:");
    printBinary(n);
    printf("\n");
    return 0;
}

说明:使用递归打印一个整数的二进制表示。


例 13 — 二进制字符串转十进制

#include <stdio.h>
#include <string.h>

int binaryToDecimal(const char *bin) {
    int result = 0;
    for (int i = 0; i < (int)strlen(bin); i++) {
        result = result * 2 + (bin[i] - '0');
    }
    return result;
}

int main(void) {
    char bin[65];
    printf("请输入二进制字符串:");
    scanf("%s", bin);
    printf("十进制为:%d\n", binaryToDecimal(bin));
    return 0;
}

说明:将一个二进制数字符串转换为十进制整数。


例 14 — 统计字符串中元音字母的个数

#include <stdio.h>
#include <string.h>
#include <ctype.h>

int main(void) {
    char str[256];
    printf("请输入一行字符串:");
    fgets(str, sizeof(str), stdin);
    int count = 0;
    for (int i = 0; i < (int)strlen(str); i++) {
        char c = tolower(str[i]);
        if (c == 'a' || c == 'e' || c == 'i' ||
            c == 'o' || c == 'u') {
            count++;
        }
    }
    printf("元音字母个数:%d\n", count);
    return 0;
}

说明:遍历字符串,并统计所有元音字符。


例 15 — 反转字符串

#include <stdio.h>
#include <string.h>

int main(void) {
    char str[256];
    printf("请输入一个字符串:");
    fgets(str, sizeof(str), stdin);
    int len = strlen(str);
    if (str[len-1] == '\n') { 
        str[len-1] = '\0'; 
        len--;
    }
    for (int i = 0; i < len / 2; i++) {
        char temp = str[i];
        str[i] = str[len - i - 1];
        str[len - i - 1] = temp;
    }
    printf("反转后的字符串:%s\n", str);
    return 0;
}

说明:利用双指针交换实现字符串反转。


例 16 — 判断回文字符串

#include <stdio.h>
#include <string.h>
#include <stdbool.h>

bool isPalindrome(const char *str) {
    int i = 0, j = strlen(str) - 1;
    while(i < j) {
        if(str[i] != str[j])
            return false;
        i++; j--;
    }
    return true;
}

int main(void) {
    char str[256];
    printf("请输入一个字符串:");
    fgets(str, sizeof(str), stdin);
    // 去除换行符
    int len = strlen(str);
    if(str[len-1]=='\n') str[len-1] = '\0';
    printf("%s\n", isPalindrome(str) ? "是回文字符串" : "不是回文字符串");
    return 0;
}

说明:判断输入的字符串是否正读与反读相同。


例 17 — 删除字符串中的元音字母

#include <stdio.h>
#include <string.h>
#include <ctype.h>

int main(void) {
    char str[256], result[256];
    printf("请输入一个字符串:");
    fgets(str, sizeof(str), stdin);
    int idx = 0;
    for (int i = 0; i < (int)strlen(str); i++) {
        char c = tolower(str[i]);
        if (c != 'a' && c != 'e' && c != 'i' && c != 'o' && c != 'u') {
            result[idx++] = str[i];
        }
    }
    result[idx] = '\0';
    printf("删除元音后的字符串:%s\n", result);
    return 0;
}

说明:遍历字符串,将非元音字符复制至新字符串。


例 18 — 冒泡排序(整型数组)

#include <stdio.h>

int main(void) {
    int n;
    printf("请输入数组元素个数:");
    scanf("%d", &n);
    int arr[n];
    printf("请输入 %d 个整数:", n);
    for(int i = 0; i < n; i++)
        scanf("%d", &arr[i]);
    // 冒泡排序
    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;
            }
    printf("排序结果:");
    for(int i = 0; i < n; i++)
        printf("%d ", arr[i]);
    printf("\n");
    return 0;
}

说明:利用冒泡排序对输入数组进行升序排序。


例 19 — 线性查找

#include <stdio.h>

int main(void) {
    int n, key;
    printf("请输入数组元素个数:");
    scanf("%d", &n);
    int arr[n];
    printf("请输入 %d 个整数:", n);
    for(int i = 0; i < n; i++)
        scanf("%d", &arr[i]);
    printf("请输入要查找的值:");
    scanf("%d", &key);
    for(int i = 0; i < n; i++) {
        if(arr[i] == key) {
            printf("找到 %d 在下标 %d 处。\n", key, i);
            return 0;
        }
    }
    printf("未找到 %d。\n", key);
    return 0;
}

说明:遍历数组查找给定目标值。


例 20 — 递归实现二分查找(要求数组已排序)

#include <stdio.h>

int binarySearch(int arr[], int left, int right, int key) {
    if (left > right)
        return -1;
    int mid = left + (right - left) / 2;
    if (arr[mid] == key)
        return mid;
    else if(arr[mid] > key)
        return binarySearch(arr, left, mid - 1, key);
    else
        return binarySearch(arr, mid + 1, right, key);
}

int main(void) {
    int n, key;
    printf("请输入数组元素个数:");
    scanf("%d", &n);
    int arr[n];
    printf("请输入 %d 个排序后的整数:", n);
    for(int i = 0; i < n; i++)
        scanf("%d", &arr[i]);
    printf("请输入要查找的值:");
    scanf("%d", &key);
    int index = binarySearch(arr, 0, n - 1, key);
    if(index != -1)
        printf("找到 %d 下标为 %d。\n", key, index);
    else
        printf("未找到 %d。\n", key);
    return 0;
}

说明:利用递归实现二分查找。


排序与搜索算法(例 21 ~ 30)

例 21 — 选择排序

#include <stdio.h>

int main(void) {
    int n;
    printf("请输入数组元素个数:");
    scanf("%d", &n);
    int arr[n];
    printf("请输入 %d 个整数:", n);
    for(int i = 0; i < n; i++)
        scanf("%d", &arr[i]);
    // 选择排序
    for(int i = 0; i < n - 1; i++) {
        int minIndex = i;
        for(int j = i + 1; j < n; j++) {
            if(arr[j] < arr[minIndex])
                minIndex = j;
        }
        int temp = arr[i];
        arr[i] = arr[minIndex];
        arr[minIndex] = temp;
    }
    printf("排序结果:");
    for(int i = 0; i < n; i++)
        printf("%d ", arr[i]);
    printf("\n");
    return 0;
}

说明:依次选择最小值进行交换实现排序。


例 22 — 插入排序

#include <stdio.h>

int main(void) {
    int n;
    printf("请输入数组元素个数:");
    scanf("%d", &n);
    int arr[n];
    printf("请输入 %d 个整数:", n);
    for(int i = 0; i < n; i++)
        scanf("%d", &arr[i]);
    // 插入排序
    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;
    }
    printf("排序结果:");
    for(int i = 0; i < n; i++)
        printf("%d ", arr[i]);
    printf("\n");
    return 0;
}

说明:通过不断比较和插入将数组排序。


例 23 — 快速排序(递归实现)

#include <stdio.h>

void quickSort(int arr[], int left, int right) {
    if (left >= right)
        return;
    int pivot = arr[(left + right) / 2];
    int i = left, j = right;
    while(i <= j) {
        while(arr[i] < pivot) i++;
        while(arr[j] > pivot) j--;
        if(i <= j) {
            int temp = arr[i];
            arr[i] = arr[j];
            arr[j] = temp;
            i++; j--;
        }
    }
    quickSort(arr, left, j);
    quickSort(arr, i, right);
}

int main(void) {
    int n;
    printf("请输入数组元素个数:");
    scanf("%d", &n);
    int arr[n];
    printf("请输入 %d 个整数:", n);
    for(int i = 0; i < n; i++)
        scanf("%d", &arr[i]);
    quickSort(arr, 0, n - 1);
    printf("排序结果:");
    for(int i = 0; i < n; i++)
        printf("%d ", arr[i]);
    printf("\n");
    return 0;
}

说明:利用递归和分治策略实现快速排序。


例 24 — 归并排序

#include <stdio.h>
#include <stdlib.h>

void merge(int arr[], int left, int mid, int right) {
    int i, j, k;
    int n1 = mid - left + 1, n2 = right - mid;
    int *L = malloc(n1 * sizeof(int));
    int *R = malloc(n2 * sizeof(int));
    for (i = 0; i < n1; i++)
        L[i] = arr[left + i];
    for (j = 0; j < n2; j++)
        R[j] = arr[mid + 1 + j];
    i = j = 0, k = left;
    while(i < n1 && j < n2) {
        if(L[i] <= R[j])
            arr[k++] = L[i++];
        else
            arr[k++] = R[j++];
    }
    while(i < n1)
        arr[k++] = L[i++];
    while(j < n2)
        arr[k++] = R[j++];
    free(L);
    free(R);
}

void mergeSort(int arr[], int left, int right) {
    if(left < right) {
        int mid = left + (right - left) / 2;
        mergeSort(arr, left, mid);
        mergeSort(arr, mid+1, right);
        merge(arr, left, mid, right);
    }
}

int main(void) {
    int n;
    printf("请输入数组元素个数:");
    scanf("%d", &n);
    int arr[n];
    printf("请输入 %d 个整数:", n);
    for(int i = 0; i < n; i++)
        scanf("%d", &arr[i]);
    mergeSort(arr, 0, n - 1);
    printf("排序结果:");
    for(int i = 0; i < n; i++)
        printf("%d ", arr[i]);
    printf("\n");
    return 0;
}

说明:使用分治法实现归并排序,对数组进行排序。


例 25 — 计数排序(仅适用于非负整数)

#include <stdio.h>
#include <stdlib.h>

int main(void) {
    int n;
    printf("请输入数组元素个数:");
    scanf("%d", &n);
    int arr[n];
    printf("请输入 %d 个非负整数:", n);
    int max = 0;
    for(int i = 0; i < n; i++){
        scanf("%d", &arr[i]);
        if(arr[i] > max)
            max = arr[i];
    }
    int *count = calloc(max + 1, sizeof(int));
    for(int i = 0; i < n; i++)
        count[arr[i]]++;
    printf("排序结果:");
    for(int i = 0; i <= max; i++)
        while(count[i]--)
            printf("%d ", i);
    printf("\n");
    free(count);
    return 0;
}

说明:利用计数数组统计各数字频率,实现排序(适用于非负整数)。


例 26 — 希尔排序

#include <stdio.h>

int main(void) {
    int n;
    printf("请输入数组元素个数:");
    scanf("%d", &n);
    int arr[n];
    printf("请输入 %d 个整数:", n);
    for (int i = 0; i < n; i++)
        scanf("%d", &arr[i]);
    // 希尔排序
    for (int gap = n/2; gap > 0; gap /= 2) {
        for (int i = gap; i < n; i++) {
            int temp = arr[i];
            int j = i;
            while (j >= gap && arr[j - gap] > temp) {
                arr[j] = arr[j - gap];
                j -= gap;
            }
            arr[j] = temp;
        }
    }
    printf("排序结果:");
    for (int i = 0; i < n; i++)
        printf("%d ", arr[i]);
    printf("\n");
    return 0;
}

说明:通过缩小增量进行插入排序,完成希尔排序。


例 27 — 桶排序(对 0~1 之间的浮点数排序)

#include <stdio.h>
#include <stdlib.h>

#define BUCKETS 10

int cmp(const void *a, const void *b) {
    float fa = *(const float*)a;
    float fb = *(const float*)b;
    return (fa > fb) - (fa < fb);
}

int main(void) {
    int n;
    printf("请输入数组元素个数:");
    scanf("%d", &n);
    float arr[n];
    printf("请输入 %d 个浮点数(0 ~ 1之间):", n);
    for (int i = 0; i < n; i++)
        scanf("%f", &arr[i]);
    
    // 创建桶
    float **buckets = malloc(BUCKETS * sizeof(float*));
    int *bucketCounts = calloc(BUCKETS, sizeof(int));
    int *bucketSizes = calloc(BUCKETS, sizeof(int));
    for (int i = 0; i < BUCKETS; i++) {
        bucketSizes[i] = n / BUCKETS + 1;
        buckets[i] = malloc(bucketSizes[i] * sizeof(float));
    }
    // 分配数据到桶中
    for (int i = 0; i < n; i++) {
        int idx = (int)(arr[i] * BUCKETS);
        if(idx >= BUCKETS) idx = BUCKETS - 1;
        buckets[idx][bucketCounts[idx]++] = arr[i];
    }
    // 桶内排序并合并
    int index = 0;
    for (int i = 0; i < BUCKETS; i++) {
        qsort(buckets[i], bucketCounts[i], sizeof(float), cmp);
        for (int j = 0; j < bucketCounts[i]; j++) {
            arr[index++] = buckets[i][j];
        }
        free(buckets[i]);
    }
    free(buckets);
    free(bucketCounts);
    free(bucketSizes);
    
    printf("排序结果:");
    for (int i = 0; i < n; i++)
        printf("%f ", arr[i]);
    printf("\n");
    return 0;
}

说明:采用桶排序对 0~1 之间的浮点数排序。


例 28 — 基数排序(适用于非负整数)

#include <stdio.h>
#include <stdlib.h>

int getMax(int arr[], int n) {
    int max = arr[0];
    for (int i = 1; i < n; i++)
        if (arr[i] > max)
            max = arr[i];
    return max;
}

void countSort(int arr[], int n, int exp) {
    int *output = malloc(n * sizeof(int));
    int count[10] = {0};
    for (int i = 0; i < n; i++)
        count[(arr[i] / exp) % 10]++;
    for (int i = 1; i < 10; i++)
        count[i] += count[i - 1];
    for (int i = n - 1; i >= 0; i--) {
        output[count[(arr[i] / exp) % 10] - 1] = arr[i];
        count[(arr[i] / exp) % 10]--;
    }
    for (int i = 0; i < n; i++)
        arr[i] = output[i];
    free(output);
}

void radixSort(int arr[], int n) {
    int max = getMax(arr, n);
    for (int exp = 1; max/exp > 0; exp *= 10)
        countSort(arr, n, exp);
}

int main(void) {
    int n;
    printf("请输入数组元素个数:");
    scanf("%d", &n);
    int *arr = malloc(n * sizeof(int));
    printf("请输入 %d 个非负整数:", n);
    for (int i = 0; i < n; i++)
        scanf("%d", &arr[i]);
    radixSort(arr, n);
    printf("排序结果:");
    for (int i = 0; i < n; i++)
        printf("%d ", arr[i]);
    printf("\n");
    free(arr);
    return 0;
}

说明:使用基数排序对非负整数数组进行排序。


例 29 — 洗牌算法(Fisher–Yates 算法)

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main(void) {
    int n;
    printf("请输入数组元素个数:");
    scanf("%d", &n);
    int arr[n];
    for (int i = 0; i < n; i++)
        arr[i] = i + 1;
    srand((unsigned)time(NULL));
    for (int i = n - 1; i > 0; i--) {
        int j = rand() % (i + 1);
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }
    printf("洗牌结果:");
    for (int i = 0; i < n; i++)
        printf("%d ", arr[i]);
    printf("\n");
    return 0;
}

说明:随机打乱数组元素顺序。


例 30 — 使用随机排序实现简单乱序(与例29类似)

// 本例与例29实现相同,故略(读者可参照例29)。

说明:此处已给出洗牌算法示例。


数据结构(例 31 ~ 40)

例 31 — 数组实现栈

#include <stdio.h>
#include <stdlib.h>
#define MAX_SIZE 100

typedef struct {
    int data[MAX_SIZE];
    int top;
} Stack;

void initStack(Stack *s) {
    s->top = -1;
}

int push(Stack *s, int value) {
    if (s->top >= MAX_SIZE - 1)
        return 0;  // 栈满
    s->data[++(s->top)] = value;
    return 1;
}

int pop(Stack *s, int *value) {
    if (s->top < 0)
        return 0;  // 栈空
    *value = s->data[(s->top)--];
    return 1;
}

int main(void) {
    Stack s;
    initStack(&s);
    push(&s, 10);
    push(&s, 20);
    int value;
    pop(&s, &value);
    printf("出栈元素:%d\n", value);
    return 0;
}

说明:利用数组实现简单的栈操作。


例 32 — 数组实现循环队列

#include <stdio.h>
#define MAX_SIZE 100

typedef struct {
    int data[MAX_SIZE];
    int front;
    int rear;
    int size;
} CircularQueue;

void initQueue(CircularQueue *q) {
    q->front = 0;
    q->rear = 0;
    q->size = 0;
}

int enqueue(CircularQueue *q, int value) {
    if (q->size == MAX_SIZE)
        return 0; // 队列满
    q->data[q->rear] = value;
    q->rear = (q->rear + 1) % MAX_SIZE;
    q->size++;
    return 1;
}

int dequeue(CircularQueue *q, int *value) {
    if (q->size == 0)
        return 0; // 队列空
    *value = q->data[q->front];
    q->front = (q->front + 1) % MAX_SIZE;
    q->size--;
    return 1;
}

int main(void) {
    CircularQueue q;
    initQueue(&q);
    enqueue(&q, 100);
    enqueue(&q, 200);
    int value;
    dequeue(&q, &value);
    printf("出队元素:%d\n", value);
    return 0;
}

说明:使用数组和环形指针实现循环队列。


例 33 — 单链表的插入与遍历

#include <stdio.h>
#include <stdlib.h>

typedef struct Node {
    int data;
    struct Node *next;
} Node;

Node* createNode(int value) {
    Node* node = malloc(sizeof(Node));
    node->data = value;
    node->next = NULL;
    return node;
}

void insertAtHead(Node **head, int value) {
    Node *node = createNode(value);
    node->next = *head;
    *head = node;
}

void traverseList(Node *head) {
    while(head) {
        printf("%d ", head->data);
        head = head->next;
    }
    printf("\n");
}

int main(void) {
    Node *head = NULL;
    insertAtHead(&head, 3);
    insertAtHead(&head, 2);
    insertAtHead(&head, 1);
    printf("链表内容:");
    traverseList(head);
    return 0;
}

说明:利用动态内存分配构建单链表,并遍历打印每个结点数据。


例 34 — 二叉树中序遍历(递归)

#include <stdio.h>
#include <stdlib.h>

typedef struct Node {
    int data;
    struct Node *left, *right;
} Node;

Node* createNode(int value) {
    Node *node = malloc(sizeof(Node));
    node->data = value;
    node->left = node->right = NULL;
    return node;
}

void inorder(Node *root) {
    if(root == NULL)
        return;
    inorder(root->left);
    printf("%d ", root->data);
    inorder(root->right);
}

int main(void) {
    // 构造简单二叉树
    Node *root = createNode(2);
    root->left = createNode(1);
    root->right = createNode(3);
    printf("中序遍历:");
    inorder(root);
    printf("\n");
    return 0;
}

说明:递归实现二叉树的中序遍历。


例 35 — 二叉搜索树的插入与查找

#include <stdio.h>
#include <stdlib.h>

typedef struct Node {
    int data;
    struct Node *left, *right;
} Node;

Node* insert(Node *root, int value) {
    if(root == NULL)
        return createNode(value);
    if(value < root->data)
        root->left = insert(root->left, value);
    else if(value > root->data)
        root->right = insert(root->right, value);
    return root;
}

Node* createNode(int value) {
    Node *node = malloc(sizeof(Node));
    node->data = value;
    node->left = node->right = NULL;
    return node;
}

int search(Node *root, int key) {
    if(root == NULL)
        return 0;
    if(root->data == key)
        return 1;
    return key < root->data ? search(root->left, key) : search(root->right, key);
}

int main(void) {
    Node *root = NULL;
    int arr[] = {5, 3, 7, 2, 4, 6, 8};
    for (int i = 0; i < 7; i++)
        root = insert(root, arr[i]);
    int key;
    printf("请输入要查找的值:");
    scanf("%d", &key);
    printf("%s\n", search(root, key) ? "找到" : "未找到");
    return 0;
}

说明:构造二叉搜索树,并实现查找功能。


例 36 — 图的深度优先搜索(邻接表存储)

#include <stdio.h>
#include <stdlib.h>

#define MAX_VERTICES 100

typedef struct Node {
    int vertex;
    struct Node *next;
} Node;

typedef struct {
    Node *head;
} List;

void addEdge(List graph[], int src, int dest) {
    Node *newNode = malloc(sizeof(Node));
    newNode->vertex = dest;
    newNode->next = graph[src].head;
    graph[src].head = newNode;
}

void dfs(List graph[], int vertex, int visited[]) {
    visited[vertex] = 1;
    printf("%d ", vertex);
    Node *temp = graph[vertex].head;
    while(temp) {
        if(!visited[temp->vertex])
            dfs(graph, temp->vertex, visited);
        temp = temp->next;
    }
}

int main(void) {
    int V = 5;
    List graph[V];
    for(int i = 0; i < V; i++)
        graph[i].head = NULL;
    addEdge(graph, 0, 1); addEdge(graph, 0, 4);
    addEdge(graph, 1, 2); addEdge(graph, 1, 3);
    addEdge(graph, 1, 4);
    addEdge(graph, 2, 3);
    addEdge(graph, 3, 4);
    int visited[V];
    for(int i = 0; i < V; i++) visited[i] = 0;
    printf("深度优先遍历:");
    dfs(graph, 0, visited);
    printf("\n");
    return 0;
}

说明:利用邻接表存储图,并用递归实现 DFS 遍历。


例 37 — 图的广度优先搜索(邻接表存储)

#include <stdio.h>
#include <stdlib.h>

#define MAX_VERTICES 100

typedef struct Node {
    int vertex;
    struct Node *next;
} Node;

typedef struct {
    Node *head;
} List;

typedef struct {
    int items[MAX_VERTICES];
    int front, rear;
} Queue;

void initQueue(Queue *q) {
    q->front = 0;
    q->rear = -1;
}

int isEmpty(Queue *q) {
    return q->rear < q->front;
}

void enqueue(Queue *q, int value) {
    q->items[++(q->rear)] = value;
}

int dequeue(Queue *q) {
    return q->items[(q->front)++];
}

void addEdge(List graph[], int src, int dest) {
    Node *newNode = malloc(sizeof(Node));
    newNode->vertex = dest;
    newNode->next = graph[src].head;
    graph[src].head = newNode;
}

void bfs(List graph[], int start, int V) {
    int visited[MAX_VERTICES] = {0};
    Queue q;
    initQueue(&q);
    visited[start] = 1;
    enqueue(&q, start);
    while(!isEmpty(&q)) {
        int current = dequeue(&q);
        printf("%d ", current);
        Node *temp = graph[current].head;
        while(temp) {
            if(!visited[temp->vertex]) {
                visited[temp->vertex] = 1;
                enqueue(&q, temp->vertex);
            }
            temp = temp->next;
        }
    }
}

int main(void) {
    int V = 5;
    List graph[V];
    for (int i = 0; i < V; i++)
        graph[i].head = NULL;
    addEdge(graph, 0, 1); addEdge(graph, 0, 4);
    addEdge(graph, 1, 2); addEdge(graph, 1, 3);
    addEdge(graph, 1, 4);
    addEdge(graph, 2, 3);
    addEdge(graph, 3, 4);
    printf("广度优先遍历:");
    bfs(graph, 0, V);
    printf("\n");
    return 0;
}

说明:利用队列实现图的广度优先搜索。


例 38 — 并查集(Union-Find)

#include <stdio.h>
#include <stdlib.h>

int find(int parent[], int i) {
    if (parent[i] == i)
        return i;
    return parent[i] = find(parent, parent[i]);
}

void unionSet(int parent[], int rank[], int x, int y) {
    int xroot = find(parent, x);
    int yroot = find(parent, y);
    if (xroot == yroot)
        return;
    if (rank[xroot] < rank[yroot])
        parent[xroot] = yroot;
    else if (rank[xroot] > rank[yroot])
        parent[yroot] = xroot;
    else {
        parent[yroot] = xroot;
        rank[xroot]++;
    }
}

int main(void) {
    int n = 5;
    int parent[n], rank[n];
    for (int i = 0; i < n; i++) {
        parent[i] = i;
        rank[i] = 0;
    }
    // 合并几个集合:例如合并 (0,1), (1,2)
    unionSet(parent, rank, 0, 1);
    unionSet(parent, rank, 1, 2);
    printf("0 和 2 %s同一个集合。\n", find(parent, 0) == find(parent, 2) ? "属于" : "不属于");
    return 0;
}

说明:利用并查集判断集合合并及查找操作。


例 39 — 简单动态数组实现

#include <stdio.h>
#include <stdlib.h>

int main(void) {
    int n;
    printf("请输入元素个数:");
    scanf("%d", &n);
    int *arr = malloc(n * sizeof(int));
    if(arr == NULL) {
        printf("内存分配失败。\n");
        return 1;
    }
    printf("请输入 %d 个整数:", n);
    for(int i = 0; i < n; i++)
        scanf("%d", &arr[i]);
    printf("动态数组内容:");
    for(int i = 0; i < n; i++)
        printf("%d ", arr[i]);
    printf("\n");
    free(arr);
    return 0;
}

说明:利用 malloc 动态分配数组内存,实现基本动态数组操作。


例 40 — 简单哈希表(开放寻址法,散列函数取模)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define TABLE_SIZE 10

typedef struct {
    int key;
    int value;
    int occupied;
} HashEntry;

void initTable(HashEntry table[]) {
    for (int i = 0; i < TABLE_SIZE; i++) {
        table[i].occupied = 0;
    }
}

int hashFunction(int key) {
    return key % TABLE_SIZE;
}

void insert(HashEntry table[], int key, int value) {
    int index = hashFunction(key);
    while(table[index].occupied) {
        index = (index + 1) % TABLE_SIZE;
    }
    table[index].key = key;
    table[index].value = value;
    table[index].occupied = 1;
}

int search(HashEntry table[], int key) {
    int index = hashFunction(key);
    int start = index;
    while(table[index].occupied) {
        if(table[index].key == key)
            return table[index].value;
        index = (index + 1) % TABLE_SIZE;
        if(index == start)
            break;
    }
    return -1; // 未找到
}

int main(void) {
    HashEntry table[TABLE_SIZE];
    initTable(table);
    insert(table, 15, 100);
    insert(table, 25, 200);
    printf("键 15 对应的值:%d\n", search(table, 15));
    printf("键 25 对应的值:%d\n", search(table, 25));
    return 0;
}

说明:用简单的开放寻址法实现哈希表的插入和查找。


递归与经典问题(例 41 ~ 50)

例 41 — 汉诺塔问题

#include <stdio.h>

void hanoi(int n, char from, char aux, char to) {
    if(n == 1) {
        printf("%c -> %c\n", from, to);
        return;
    }
    hanoi(n-1, from, to, aux);
    printf("%c -> %c\n", from, to);
    hanoi(n-1, aux, from, to);
}

int main(void) {
    int n;
    printf("请输入盘子的数量:");
    scanf("%d", &n);
    hanoi(n, 'A', 'B', 'C');
    return 0;
}

说明:递归解决汉诺塔问题。


例 42 — N 皇后问题(求解方案数)

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

int N, solutions = 0;
int *col, *diag1, *diag2;

void solve(int row) {
    if(row == N) {
        solutions++;
        return;
    }
    for (int c = 0; c < N; c++) {
        if (!col[c] && !diag1[row+c] && !diag2[row-c+N-1]) {
            col[c] = diag1[row+c] = diag2[row-c+N-1] = 1;
            solve(row + 1);
            col[c] = diag1[row+c] = diag2[row-c+N-1] = 0;
        }
    }
}

int main(void) {
    printf("请输入皇后个数:");
    scanf("%d", &N);
    col = calloc(N, sizeof(int));
    diag1 = calloc(2*N-1, sizeof(int));
    diag2 = calloc(2*N-1, sizeof(int));
    solve(0);
    printf("共有 %d 种解法。\n", solutions);
    free(col); free(diag1); free(diag2);
    return 0;
}

说明:采用回溯法求解 N 皇后问题。


例 43 — 全排列(递归生成数组排列)

#include <stdio.h>
#include <stdlib.h>

void swap(int *a, int *b) {
    int temp = *a; *a = *b; *b = temp;
}

void permute(int arr[], int l, int r) {
    if (l == r) {
        for (int i = 0; i <= r; i++)
            printf("%d ", arr[i]);
        printf("\n");
    } else {
        for (int i = l; i <= r; i++) {
            swap(&arr[l], &arr[i]);
            permute(arr, l+1, r);
            swap(&arr[l], &arr[i]);  // 回溯
        }
    }
}

int main(void) {
    int n;
    printf("请输入数组元素个数:");
    scanf("%d", &n);
    int *arr = malloc(n * sizeof(int));
    printf("请输入 %d 个整数:", n);
    for (int i = 0; i < n; i++)
        scanf("%d", &arr[i]);
    printf("全排列结果:\n");
    permute(arr, 0, n-1);
    free(arr);
    return 0;
}

说明:利用递归生成数组的所有排列组合。


例 44 — 帕斯卡三角形

#include <stdio.h>
#include <stdlib.h>

int main(void) {
    int n;
    printf("请输入行数:");
    scanf("%d", &n);
    int **triangle = malloc(n * sizeof(int *));
    for (int i = 0; i < n; i++) {
        triangle[i] = malloc((i+1) * sizeof(int));
        for (int j = 0; j <= i; j++) {
            if(j == 0 || j == i)
                triangle[i][j] = 1;
            else
                triangle[i][j] = triangle[i-1][j-1] + triangle[i-1][j];
            printf("%d ", triangle[i][j]);
        }
        printf("\n");
    }
    for (int i = 0; i < n; i++)
        free(triangle[i]);
    free(triangle);
    return 0;
}

说明:利用二维数组构造并打印帕斯卡三角形。


例 45 — 泰勒级数展开计算 sin(x)(近似)

#include <stdio.h>

double mysin(double x, int terms) {
    double sum = 0;
    double term = x;
    int sign = 1;
    for (int i = 1, j = 1; i <= terms; i++, j += 2) {
        sum += sign * term;
        term = term * x * x / ((j + 1) * (j + 2));
        sign = -sign;
    }
    return sum;
}

int main(void) {
    double x;
    printf("请输入角度(弧度):");
    scanf("%lf", &x);
    printf("sin(%.2lf) ≈ %lf\n", x, mysin(x, 10));
    return 0;
}

说明:利用泰勒展开近似计算 sin(x) 值。


例 46 — 简易命令行计算器

#include <stdio.h>

int main(void) {
    double a, b;
    char op;
    printf("输入计算表达式(例如 3.5 + 2.1):");
    scanf("%lf %c %lf", &a, &op, &b);
    switch(op) {
        case '+': printf("结果:%lf\n", a + b); break;
        case '-': printf("结果:%lf\n", a - b); break;
        case '*': printf("结果:%lf\n", a * b); break;
        case '/': 
            if(b != 0)
                printf("结果:%lf\n", a / b);
            else
                printf("错误:除数为 0\n");
            break;
        default: printf("不支持的运算符\n");
    }
    return 0;
}

说明:利用 switch-case 实现简单的四则运算计算器。


例 47 — 贪心算法解决找零问题

#include <stdio.h>

int main(void) {
    int amount;
    int coins[] = {50, 20, 10, 5, 1};
    int n = sizeof(coins) / sizeof(coins[0]);
    printf("请输入找零金额:");
    scanf("%d", &amount);
    printf("找零方案:\n");
    for(int i = 0; i < n; i++) {
        int num = amount / coins[i];
        amount %= coins[i];
        printf("面额 %d: %d 个\n", coins[i], num);
    }
    return 0;
}

说明:采用贪心策略,计算不同面额的硬币数量。


例 48 — 0/1 背包问题(动态规划实现)

#include <stdio.h>
#include <stdlib.h>

int max(int a, int b) {
    return a > b ? a : b;
}

int main(void) {
    int n, W;
    printf("请输入物品数和背包容量:");
    scanf("%d %d", &n, &W);
    int *weights = malloc(n * sizeof(int));
    int *values = malloc(n * sizeof(int));
    printf("请输入每个物品的重量和价值:\n");
    for (int i = 0; i < n; i++)
        scanf("%d %d", &weights[i], &values[i]);
    
    int **dp = malloc((n+1) * sizeof(int *));
    for (int i = 0; i <= n; i++) {
        dp[i] = calloc(W+1, sizeof(int));
    }
    for (int i = 1; i <= n; i++) {
        for (int w = 1; w <= W; w++) {
            if (weights[i-1] <= w)
                dp[i][w] = max(dp[i-1][w], dp[i-1][w-weights[i-1]] + values[i-1]);
            else
                dp[i][w] = dp[i-1][w];
        }
    }
    printf("最大价值:%d\n", dp[n][W]);
    
    for (int i = 0; i <= n; i++)
        free(dp[i]);
    free(dp); free(weights); free(values);
    return 0;
}

说明:利用二维动态规划数组实现 0/1 背包问题求最大价值。


例 49 — 大数阶乘(利用数组存储每位数字)

#include <stdio.h>
#include <string.h>

#define MAX_DIGITS 1000

int main(void) {
    int n;
    printf("请输入整数 n:");
    scanf("%d", &n);
    int result[MAX_DIGITS] = {0};
    result[0] = 1;
    int len = 1;
    for (int x = 2; x <= n; x++) {
        int carry = 0;
        for (int i = 0; i < len; i++) {
            int prod = result[i] * x + carry;
            result[i] = prod % 10;
            carry = prod / 10;
        }
        while(carry) {
            result[len++] = carry % 10;
            carry /= 10;
        }
    }
    printf("%d! = ", n);
    for (int i = len - 1; i >= 0; i--)
        printf("%d", result[i]);
    printf("\n");
    return 0;
}

说明:利用数组模拟大整数乘法,计算 n 的阶乘。


例 50 — KMP 算法实现字符串匹配

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

void computeLPS(const char *pat, int M, int *lps) {
    int length = 0;
    lps[0] = 0;
    int i = 1;
    while(i < M) {
        if(pat[i] == pat[length]) {
            length++;
            lps[i] = length;
            i++;
        } else {
            if(length != 0)
                length = lps[length - 1];
            else {
                lps[i] = 0;
                i++;
            }
        }
    }
}

void KMPSearch(const char *txt, const char *pat) {
    int N = strlen(txt);
    int M = strlen(pat);
    int *lps = malloc(M * sizeof(int));
    computeLPS(pat, M, lps);
    int i = 0, j = 0;
    while(i < N) {
        if(pat[j] == txt[i]) {
            i++; j++;
        }
        if(j == M) {
            printf("找到匹配,位置:%d\n", i - j);
            j = lps[j - 1];
        } else if(i < N && pat[j] != txt[i]) {
            if(j != 0)
                j = lps[j - 1];
            else
                i++;
        }
    }
    free(lps);
}

int main(void) {
    char txt[256], pat[256];
    printf("请输入文本:");
    scanf("%s", txt);
    printf("请输入模式串:");
    scanf("%s", pat);
    KMPSearch(txt, pat);
    return 0;
}

说明:利用 KMP 算法进行字符串匹配,并输出匹配位置。


指针与内存管理(例 51 ~ 60)

例 51 — 指针基本使用及地址输出

#include <stdio.h>

int main(void) {
    int a = 10;
    int *p = &a;
    printf("a = %d, 地址 = %p\n", a, (void*)&a);
    printf("指针 p 的值 = %p, *p = %d\n", (void*)p, *p);
    return 0;
}

说明:演示变量与指针的基本用法及输出地址。


例 52 — 指针算术运算示例

#include <stdio.h>

int main(void) {
    int arr[] = {10, 20, 30, 40, 50};
    int *p = arr;
    printf("数组地址:%p\n", (void*)arr);
    printf("指针 p 初始指向:%d\n", *p);
    p++;
    printf("p++ 后指向:%d\n", *p);
    return 0;
}

说明:展示指针自增及数组元素访问。


例 53 — 动态内存分配(malloc 和 free 示例)

#include <stdio.h>
#include <stdlib.h>

int main(void) {
    int n;
    printf("请输入动态数组大小:");
    scanf("%d", &n);
    int *arr = malloc(n * sizeof(int));
    if(arr == NULL) {
        printf("内存分配失败!\n");
        return 1;
    }
    for (int i = 0; i < n; i++)
        arr[i] = i + 1;
    printf("动态数组内容:");
    for (int i = 0; i < n; i++)
        printf("%d ", arr[i]);
    printf("\n");
    free(arr);
    return 0;
}

说明:使用 malloc 分配内存,并在使用后调用 free 释放。


例 54 — 利用指针交换两个数(传地址方式)

#include <stdio.h>

void swap(int *a, int *b) {
    int temp = *a;
    *a = *b;
    *b = temp;
}

int main(void) {
    int x = 5, y = 10;
    printf("交换前:x = %d, y = %d\n", x, y);
    swap(&x, &y);
    printf("交换后:x = %d, y = %d\n", x, y);
    return 0;
}

说明:演示通过函数和指针交换两个变量的值。


例 55 — 利用指针反转数组

#include <stdio.h>

void reverseArray(int *arr, int n) {
    int *start = arr, *end = arr + n - 1;
    while(start < end) {
        int temp = *start;
        *start = *end;
        *end = temp;
        start++; end--;
    }
}

int main(void) {
    int n;
    printf("请输入数组大小:");
    scanf("%d", &n);
    int arr[n];
    printf("请输入 %d 个整数:", n);
    for (int i = 0; i < n; i++)
        scanf("%d", &arr[i]);
    reverseArray(arr, n);
    printf("反转后的数组:");
    for (int i = 0; i < n; i++)
        printf("%d ", arr[i]);
    printf("\n");
    return 0;
}

说明:通过指针操作交换数组元素,实现数组反转。


例 56 — 演示内存泄漏与修复

#include <stdio.h>
#include <stdlib.h>

int main(void) {
    // 内存泄漏示例
    int *ptr = malloc(10 * sizeof(int));
    if(ptr == NULL) {
        printf("内存分配失败\n");
        return 1;
    }
    // 进行一些操作……
    // 忘记调用 free(ptr);
    // 修复方法:调用 free(ptr) 释放内存
    free(ptr);
    printf("内存已释放,避免内存泄漏。\n");
    return 0;
}

说明:示范内存分配后及时释放,避免内存泄漏。


例 57 — 双重指针使用(指针数组示例)

#include <stdio.h>

int main(void) {
    int a = 100;
    int *p = &a;
    int **pp = &p;
    printf("a = %d\n", a);
    printf("*p = %d\n", *p);
    printf("**pp = %d\n", **pp);
    return 0;
}

说明:演示二级指针的基本用法。


例 58 — 利用动态内存构造链表(malloc实现)

#include <stdio.h>
#include <stdlib.h>

typedef struct Node {
    int data;
    struct Node *next;
} Node;

Node* createNode(int value) {
    Node *node = malloc(sizeof(Node));
    node->data = value;
    node->next = NULL;
    return node;
}

void insertAtHead(Node **head, int value) {
    Node *node = createNode(value);
    node->next = *head;
    *head = node;
}

void traverseList(Node *head) {
    while(head) {
        printf("%d ", head->data);
        head = head->next;
    }
    printf("\n");
}

int main(void) {
    Node *head = NULL;
    insertAtHead(&head, 10);
    insertAtHead(&head, 20);
    insertAtHead(&head, 30);
    printf("链表内容:");
    traverseList(head);
    return 0;
}

说明:动态分配内存构造链表,实现基本插入和遍历。


例 59 — 结构体指针的基本使用

#include <stdio.h>
#include <stdlib.h>

typedef struct {
    int id;
    char name[50];
} Person;

int main(void) {
    Person *p = malloc(sizeof(Person));
    p->id = 1;
    snprintf(p->name, sizeof(p->name), "Alice");
    printf("ID: %d, Name: %s\n", p->id, p->name);
    free(p);
    return 0;
}

说明:演示如何使用结构体指针存取数据。


例 60 — 函数指针示例(简单回调)

#include <stdio.h>

int add(int a, int b) {
    return a + b;
}

int operate(int a, int b, int (*op)(int, int)) {
    return op(a, b);
}

int main(void) {
    int result = operate(5, 3, add);
    printf("结果:%d\n", result);
    return 0;
}

说明:通过函数指针实现回调机制。


文件 I/O 与错误处理(例 61 ~ 70)

例 61 — 写入文本到文件

#include <stdio.h>

int main(void) {
    FILE *fp = fopen("output.txt", "w");
    if(fp == NULL) {
        perror("打开文件失败");
        return 1;
    }
    fprintf(fp, "Hello, File!\n");
    fclose(fp);
    printf("写入文件成功。\n");
    return 0;
}

说明:将文本写入文件,并检查打开文件是否成功。


例 62 — 读取文件逐行输出

#include <stdio.h>
#include <stdlib.h>

int main(void) {
    FILE *fp = fopen("output.txt", "r");
    if(fp == NULL) {
        perror("打开文件失败");
        return 1;
    }
    char line[256];
    while(fgets(line, sizeof(line), fp)) {
        printf("%s", line);
    }
    fclose(fp);
    return 0;
}

说明:逐行读取文件内容并输出到屏幕。


例 63 — 文件复制

#include <stdio.h>
#include <stdlib.h>

int main(void) {
    FILE *src = fopen("output.txt", "r");
    if(src == NULL) {
        perror("打开源文件失败");
        return 1;
    }
    FILE *dest = fopen("copy.txt", "w");
    if(dest == NULL) {
        perror("打开目标文件失败");
        fclose(src);
        return 1;
    }
    char buffer[1024];
    size_t bytes;
    while((bytes = fread(buffer, 1, sizeof(buffer), src)) > 0)
        fwrite(buffer, 1, bytes, dest);
    fclose(src);
    fclose(dest);
    printf("文件复制成功。\n");
    return 0;
}

说明:利用 fread 和 fwrite 实现二进制文件复制。


例 64 — 统计文件中单词数

#include <stdio.h>
#include <ctype.h>

int main(void) {
    FILE *fp = fopen("output.txt", "r");
    if(fp == NULL) {
        perror("打开文件失败");
        return 1;
    }
    int c, prev = ' ';
    int words = 0;
    while ((c = fgetc(fp)) != EOF) {
        if(isspace(prev) && !isspace(c))
            words++;
        prev = c;
    }
    fclose(fp);
    printf("单词总数:%d\n", words);
    return 0;
}

说明:遍历文件字符,统计单词的数量。


例 65 — 向文件追加文本

#include <stdio.h>

int main(void) {
    FILE *fp = fopen("output.txt", "a");
    if(fp == NULL) {
        perror("打开文件失败");
        return 1;
    }
    fprintf(fp, "追加一行文本。\n");
    fclose(fp);
    printf("文件追加成功。\n");
    return 0;
}

说明:以追加模式打开文件,并写入新内容。


例 66 — CSV 文件读取简单示例

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void) {
    FILE *fp = fopen("data.csv", "r");
    if(fp == NULL) {
        perror("打开 CSV 文件失败");
        return 1;
    }
    char line[256];
    while(fgets(line, sizeof(line), fp)) {
        char *token = strtok(line, ",");
        while(token) {
            printf("%s ", token);
            token = strtok(NULL, ",");
        }
        printf("\n");
    }
    fclose(fp);
    return 0;
}

说明:读取 CSV 文件每行内容,并使用 strtok 分割数据。


例 67 — 二进制文件读写

#include <stdio.h>
#include <stdlib.h>

typedef struct {
    int id;
    float value;
} Data;

int main(void) {
    Data d = {1, 3.14f};
    FILE *fp = fopen("data.bin", "wb");
    if(fp == NULL) {
        perror("打开文件失败");
        return 1;
    }
    fwrite(&d, sizeof(Data), 1, fp);
    fclose(fp);
    
    Data d2;
    fp = fopen("data.bin", "rb");
    if(fp == NULL) {
        perror("打开文件失败");
        return 1;
    }
    fread(&d2, sizeof(Data), 1, fp);
    fclose(fp);
    
    printf("读取二进制数据:id = %d, value = %f\n", d2.id, d2.value);
    return 0;
}

说明:示范如何写入和读取二进制数据结构。


例 68 — 文件定位(fseek 和 ftell)

#include <stdio.h>

int main(void) {
    FILE *fp = fopen("output.txt", "r");
    if(fp == NULL) {
        perror("打开文件失败");
        return 1;
    }
    fseek(fp, 0, SEEK_END);
    long pos = ftell(fp);
    printf("文件大小:%ld 字节\n", pos);
    fclose(fp);
    return 0;
}

说明:利用 fseek 定位文件尾,并用 ftell 获取文件大小。


例 69 — 文件错误处理示例

#include <stdio.h>

int main(void) {
    FILE *fp = fopen("nonexistent.txt", "r");
    if(fp == NULL) {
        perror("错误");
        return 1;
    }
    fclose(fp);
    return 0;
}

说明:演示打开文件失败时的错误处理。


例 70 — 简单日志记录功能(写日志到文件)

#include <stdio.h>
#include <time.h>

int main(void) {
    FILE *logfile = fopen("log.txt", "a");
    if(logfile == NULL) {
        perror("打开日志文件失败");
        return 1;
    }
    time_t now = time(NULL);
    fprintf(logfile, "Log entry at %s", ctime(&now));
    fclose(logfile);
    printf("日志已记录。\n");
    return 0;
}

说明:将当前时间戳写入日志文件,作为简单日志记录示例。


位操作与数值运算(例 71 ~ 80)

例 71 — 位操作基本演示(AND, OR, XOR, NOT)

#include <stdio.h>

int main(void) {
    unsigned int a = 5, b = 9;
    printf("a & b = %u\n", a & b);
    printf("a | b = %u\n", a | b);
    printf("a ^ b = %u\n", a ^ b);
    printf("~a = %u\n", ~a);
    return 0;
}

说明:演示常用的位操作符的使用。


例 72 — 使用位操作判断奇偶性

#include <stdio.h>

int main(void) {
    int n;
    printf("请输入一个整数:");
    scanf("%d", &n);
    if(n & 1)
        printf("%d 是奇数。\n", n);
    else
        printf("%d 是偶数。\n", n);
    return 0;
}

说明:通过 n & 1 判断整数奇偶。


例 73 — 统计整数中1的个数(位计数)

#include <stdio.h>

int countSetBits(unsigned int n) {
    int count = 0;
    while(n) {
        count += n & 1;
        n >>= 1;
    }
    return count;
}

int main(void) {
    unsigned int n;
    printf("请输入一个非负整数:");
    scanf("%u", &n);
    printf("二进制中 1 的个数:%d\n", countSetBits(n));
    return 0;
}

说明:统计整数二进制表示中 1 的个数。


例 74 — 判断一个数是否是 2 的幂(位运算实现)

#include <stdio.h>
#include <stdbool.h>

bool isPowerOfTwo(unsigned int n) {
    return n && !(n & (n - 1));
}

int main(void) {
    unsigned int n;
    printf("请输入一个整数:");
    scanf("%u", &n);
    printf("%u %s 2 的幂。\n", n, isPowerOfTwo(n) ? "是" : "不是");
    return 0;
}

说明:利用 n & (n - 1) 判断是否为 2 的幂。


例 75 — 位旋转操作(左旋转和右旋转)

#include <stdio.h>

unsigned int rotateLeft(unsigned int n, int d) {
    return (n << d) | (n >> (32 - d));
}

unsigned int rotateRight(unsigned int n, int d) {
    return (n >> d) | (n << (32 - d));
}

int main(void) {
    unsigned int n = 0x12345678;
    printf("原数:0x%X\n", n);
    printf("左旋 8 位:0x%X\n", rotateLeft(n, 8));
    printf("右旋 8 位:0x%X\n", rotateRight(n, 8));
    return 0;
}

说明:演示整数的位旋转操作。


例 76 — 反转一个整数的所有位(32位整数)

#include <stdio.h>

unsigned int reverseBits(unsigned int n) {
    unsigned int result = 0;
    for (int i = 0; i < 32; i++) {
        result <<= 1;
        result |= (n & 1);
        n >>= 1;
    }
    return result;
}

int main(void) {
    unsigned int n = 0xF0F0F0F0;
    printf("反转前:0x%X\n", n);
    printf("反转后:0x%X\n", reverseBits(n));
    return 0;
}

说明:逐位反转一个 32 位整数的二进制表示。


例 77 — 检测系统字节序(大小端)

#include <stdio.h>
#include <stdbool.h>

bool isLittleEndian() {
    unsigned int x = 1;
    return *((char*)&x) == 1;
}

int main(void) {
    printf("系统是 %s 字节序。\n", isLittleEndian() ? "小端" : "大端");
    return 0;
}

说明:通过检查低地址字节判断系统字节序。


例 78 — 位掩码提取示例

#include <stdio.h>

int main(void) {
    unsigned int number = 0xDEADBEEF;
    // 提取中间 8 位:位 16~23
    unsigned int mask = 0x00FF0000;
    unsigned int extracted = (number & mask) >> 16;
    printf("提取的值:0x%X\n", extracted);
    return 0;
}

说明:利用位掩码提取指定区域的比特位。


例 79 — 快速幂(使用位运算实现)

#include <stdio.h>

long long fastPow(long long base, long long exp) {
    long long result = 1;
    while(exp > 0) {
        if(exp & 1)
            result *= base;
        base *= base;
        exp >>= 1;
    }
    return result;
}

int main(void) {
    long long base, exp;
    printf("请输入底数和指数:");
    scanf("%lld %lld", &base, &exp);
    printf("结果:%lld\n", fastPow(base, exp));
    return 0;
}

说明:采用快速幂算法高效计算大整数幂。


例 80 — 打印整数的二进制表示(位操作实现)

#include <stdio.h>

void printBinary(unsigned int n) {
    for (int i = 31; i >= 0; i--) {
        printf("%u", (n >> i) & 1);
        if(i % 8 == 0)
            printf(" ");
    }
    printf("\n");
}

int main(void) {
    unsigned int n;
    printf("请输入一个整数:");
    scanf("%u", &n);
    printBinary(n);
    return 0;
}

说明:利用位移和掩码打印 32 位整数的二进制表示,每 8 位分隔一次。


实用算法与综合实例(例 81 ~ 90)

例 81 — 后缀表达式求值(逆波兰表达式)

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>

#define STACK_MAX 100

typedef struct {
    int data[STACK_MAX];
    int top;
} Stack;

void initStack(Stack *s) {
    s->top = -1;
}

int push(Stack *s, int value) {
    if(s->top >= STACK_MAX - 1)
        return 0;
    s->data[++(s->top)] = value;
    return 1;
}

int pop(Stack *s, int *value) {
    if(s->top < 0)
        return 0;
    *value = s->data[(s->top)--];
    return 1;
}

int evaluatePostfix(const char *expr) {
    Stack s;
    initStack(&s);
    for(int i = 0; expr[i] != '\0'; i++) {
        if(isdigit(expr[i])) {
            push(&s, expr[i] - '0');
        } else if(expr[i] == ' ') {
            continue;
        } else {
            int val2, val1;
            pop(&s, &val2);
            pop(&s, &val1);
            switch(expr[i]) {
                case '+': push(&s, val1 + val2); break;
                case '-': push(&s, val1 - val2); break;
                case '*': push(&s, val1 * val2); break;
                case '/': push(&s, val1 / val2); break;
            }
        }
    }
    int result;
    pop(&s, &result);
    return result;
}

int main(void) {
    char expr[256];
    printf("请输入逆波兰表达式(数字和运算符之间以空格分隔):\n");
    fgets(expr, sizeof(expr), stdin);
    printf("结果:%d\n", evaluatePostfix(expr));
    return 0;
}

说明:使用栈数据结构求解后缀表达式。


例 82 — 中缀表达式转后缀表达式并求值

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>

#define STACK_MAX 100

typedef struct {
    char data[STACK_MAX];
    int top;
} CharStack;

void initCharStack(CharStack *s) {
    s->top = -1;
}

void pushChar(CharStack *s, char c) {
    s->data[++(s->top)] = c;
}

char popChar(CharStack *s) {
    return s->data[(s->top)--];
}

char peekChar(CharStack *s) {
    return s->data[s->top];
}

int precedence(char op) {
    if(op == '+' || op == '-')
        return 1;
    if(op == '*' || op == '/')
        return 2;
    return 0;
}

void infixToPostfix(const char *infix, char *postfix) {
    CharStack s;
    initCharStack(&s);
    int j = 0;
    for (int i = 0; infix[i] != '\0'; i++) {
        if(isdigit(infix[i])) {
            postfix[j++] = infix[i];
        } else if(infix[i] == ' ') {
            postfix[j++] = ' ';
        } else {
            while(s.top != -1 && precedence(peekChar(&s)) >= precedence(infix[i]))
                postfix[j++] = popChar(&s);
            pushChar(&s, infix[i]);
        }
    }
    while(s.top != -1)
        postfix[j++] = popChar(&s);
    postfix[j] = '\0';
}

int evaluateExpression(const char *expr) {
    // 直接调用前面例81的后缀求值函数
    return evaluatePostfix(expr);
}

// 此处复用例81中的 evaluatePostfix() 实现

int main(void) {
    char infix[256], postfix[256];
    printf("请输入中缀表达式(单字符操作数):\n");
    fgets(infix, sizeof(infix), stdin);
    infixToPostfix(infix, postfix);
    printf("后缀表达式为:%s\n", postfix);
    printf("计算结果:%d\n", evaluateExpression(postfix));
    return 0;
}

说明:先将中缀表达式转换为后缀表达式,再利用后缀求值方法计算结果。


例 83 — 简易命令行计算器(循环读取输入)

#include <stdio.h>
#include <stdlib.h>

int main(void) {
    char line[256];
    printf("简单计算器(输入 exit 退出):\n");
    while(1) {
        printf(">>> ");
        if(fgets(line, sizeof(line), stdin) == NULL)
            break;
        if(strncmp(line, "exit", 4) == 0)
            break;
        double a, b;
        char op;
        if(sscanf(line, "%lf %c %lf", &a, &op, &b) == 3) {
            switch(op) {
                case '+': printf("结果:%lf\n", a + b); break;
                case '-': printf("结果:%lf\n", a - b); break;
                case '*': printf("结果:%lf\n", a * b); break;
                case '/': 
                    if(b != 0)
                        printf("结果:%lf\n", a / b);
                    else
                        printf("错误:除数为0\n");
                    break;
                default: printf("不支持的运算符。\n");
            }
        } else {
            printf("输入格式错误,请重试。\n");
        }
    }
    return 0;
}

说明:通过循环不断读取用户输入,实现持续计算功能。


例 84 — 矩阵乘法

#include <stdio.h>
#include <stdlib.h>

int main(void) {
    int m, n, p;
    printf("请输入矩阵 A 的行数和列数:");
    scanf("%d %d", &m, &n);
    printf("请输入矩阵 B 的列数(A 的列数 = B 的行数):");
    scanf("%d", &p);
    
    int **A = malloc(m * sizeof(int *));
    int **B = malloc(n * sizeof(int *));
    int **C = malloc(m * sizeof(int *));
    for(int i = 0; i < m; i++) {
        A[i] = malloc(n * sizeof(int));
        C[i] = calloc(p, sizeof(int));
    }
    for(int i = 0; i < n; i++)
        B[i] = malloc(p * sizeof(int));
    
    printf("请输入矩阵 A:\n");
    for(int i = 0; i < m; i++)
        for(int j = 0; j < n; j++)
            scanf("%d", &A[i][j]);
    
    printf("请输入矩阵 B:\n");
    for(int i = 0; i < n; i++)
        for(int j = 0; j < p; j++)
            scanf("%d", &B[i][j]);
    
    // 计算矩阵乘法:C = A * B
    for(int i = 0; i < m; i++)
        for(int j = 0; j < p; j++)
            for(int k = 0; k < n; k++)
                C[i][j] += A[i][k] * B[k][j];
    
    printf("结果矩阵 C:\n");
    for(int i = 0; i < m; i++) {
        for(int j = 0; j < p; j++)
            printf("%d ", C[i][j]);
        printf("\n");
    }
    
    // 释放内存
    for(int i = 0; i < m; i++) { free(A[i]); free(C[i]); }
    for(int i = 0; i < n; i++) free(B[i]);
    free(A); free(B); free(C);
    
    return 0;
}

说明:动态分配二维数组,并实现矩阵乘法运算。


例 85 — 矩阵快速幂求斐波那契数(2×2 矩阵)

#include <stdio.h>
#include <stdlib.h>

typedef struct {
    long long m[2][2];
} Matrix;

Matrix multiply(Matrix a, Matrix b) {
    Matrix c = {{{0,0},{0,0}}};
    for (int i = 0; i < 2; i++)
        for (int j = 0; j < 2; j++)
            for (int k = 0; k < 2; k++)
                c.m[i][j] += a.m[i][k] * b.m[k][j];
    return c;
}

Matrix matrixPow(Matrix a, int n) {
    Matrix result = {{{1,0},{0,1}}};
    while(n) {
        if(n & 1)
            result = multiply(result, a);
        a = multiply(a, a);
        n >>= 1;
    }
    return result;
}

int main(void) {
    int n;
    printf("请输入斐波那契数的项数:");
    scanf("%d", &n);
    if(n == 0) {
        printf("0\n");
        return 0;
    }
    Matrix base = {{{1,1},{1,0}}};
    Matrix result = matrixPow(base, n-1);
    printf("斐波那契数 F(%d) = %lld\n", n, result.m[0][0]);
    return 0;
}

说明:利用矩阵快速幂实现高效计算斐波那契数列。


例 86 — Dijkstra 算法求最短路径(单源最短路径)

#include <stdio.h>
#include <limits.h>
#include <stdbool.h>

#define V 5

int minDistance(int dist[], bool sptSet[]) {
    int min = INT_MAX, min_index;
    for (int v = 0; v < V; v++)
        if (!sptSet[v] && dist[v] <= min) {
            min = dist[v];
            min_index = v;
        }
    return min_index;
}

void dijkstra(int graph[V][V], int src) {
    int dist[V];
    bool sptSet[V] = {false};
    for (int i = 0; i < V; i++)
        dist[i] = INT_MAX;
    dist[src] = 0;
    
    for (int count = 0; count < V - 1; count++) {
        int u = minDistance(dist, sptSet);
        sptSet[u] = true;
        for (int v = 0; v < V; v++)
            if (!sptSet[v] && graph[u][v] && dist[u] != INT_MAX
               && dist[u] + graph[u][v] < dist[v])
                dist[v] = dist[u] + graph[u][v];
    }
    printf("顶点   距离\n");
    for (int i = 0; i < V; i++)
        printf("%d \t %d\n", i, dist[i]);
}

int main(void) {
    int graph[V][V] = {
        {0, 10, 0, 5, 0},
        {0, 0, 1, 2, 0},
        {0, 0, 0, 0, 4},
        {0, 3, 9, 0, 2},
        {7, 0, 6, 0, 0}
    };
    dijkstra(graph, 0);
    return 0;
}

说明:使用 Dijkstra 算法计算给定图从源点的最短路径。


例 87 — 拓扑排序(Kahn 算法)

#include <stdio.h>
#include <stdlib.h>

#define MAX_VERTICES 100

typedef struct {
    int *data;
    int front, rear;
    int size;
} Queue;

void initQueue(Queue *q, int size) {
    q->data = malloc(size * sizeof(int));
    q->front = 0;
    q->rear = -1;
    q->size = size;
}

int isEmpty(Queue *q) {
    return q->rear < q->front;
}

void enqueue(Queue *q, int value) {
    q->data[++(q->rear)] = value;
}

int dequeue(Queue *q) {
    return q->data[(q->front)++];
}

void topologicalSort(int graph[MAX_VERTICES][MAX_VERTICES], int V, int inDegree[]) {
    Queue q;
    initQueue(&q, V);
    for (int i = 0; i < V; i++)
        if(inDegree[i] == 0)
            enqueue(&q, i);
    printf("拓扑排序结果:");
    while(!isEmpty(&q)) {
        int u = dequeue(&q);
        printf("%d ", u);
        for (int v = 0; v < V; v++) {
            if(graph[u][v]) {
                inDegree[v]--;
                if(inDegree[v] == 0)
                    enqueue(&q, v);
            }
        }
    }
    printf("\n");
    free(q.data);
}

int main(void) {
    int V = 6;
    // 邻接矩阵表示有向图
    int graph[MAX_VERTICES][MAX_VERTICES] = {0};
    // 手动构造图
    graph[5][2] = 1; graph[5][0] = 1;
    graph[4][0] = 1; graph[4][1] = 1;
    graph[2][3] = 1;
    graph[3][1] = 1;
    int inDegree[MAX_VERTICES] = {0};
    for (int i = 0; i < V; i++)
        for (int j = 0; j < V; j++)
            if(graph[i][j])
                inDegree[j]++;
    topologicalSort(graph, V, inDegree);
    return 0;
}

说明:使用 Kahn 算法实现拓扑排序,适用于有向无环图。


例 88 — “猜数字”游戏

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main(void) {
    int number, guess, attempts = 0;
    srand((unsigned)time(NULL));
    number = rand() % 100 + 1;
    printf("猜数字游戏(1~100):\n");
    do {
        printf("请输入你的猜测:");
        scanf("%d", &guess);
        attempts++;
        if(guess < number)
            printf("太小了!\n");
        else if(guess > number)
            printf("太大了!\n");
        else
            printf("恭喜你,猜对了!共猜了 %d 次。\n", attempts);
    } while(guess != number);
    return 0;
}

说明:实现一个交互式的猜数字小游戏。


例 89 — 简易“石头剪子布”游戏

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main(void) {
    srand((unsigned)time(NULL));
    int choice, comp = rand() % 3;
    printf("请选择:0-石头,1-剪刀,2-布:");
    scanf("%d", &choice);
    printf("电脑选择:%s\n", comp==0?"石头":comp==1?"剪刀":"布");
    if(choice == comp)
        printf("平局!\n");
    else if((choice == 0 && comp == 1) || (choice == 1 && comp == 2) || (choice == 2 && comp == 0))
        printf("你赢了!\n");
    else
        printf("你输了!\n");
    return 0;
}

说明:模拟“石头剪子布”游戏,随机生成电脑选择。


例 90 — “井字棋”游戏(简易版)

#include <stdio.h>
#include <stdlib.h>

char board[3][3];

void initBoard() {
    for (int i = 0; i < 3; i++)
        for (int j = 0; j < 3; j++)
            board[i][j] = ' ';
}

void printBoard() {
    printf("\n");
    for (int i = 0; i < 3; i++) {
        printf(" %c | %c | %c ", board[i][0], board[i][1], board[i][2]);
        if(i < 2)
            printf("\n---|---|---\n");
    }
    printf("\n");
}

int checkWin() {
    for (int i = 0; i < 3; i++) {
        if(board[i][0] != ' ' &&
           board[i][0] == board[i][1] &&
           board[i][1] == board[i][2])
            return 1;
        if(board[0][i] != ' ' &&
           board[0][i] == board[1][i] &&
           board[1][i] == board[2][i])
            return 1;
    }
    if(board[0][0] != ' ' &&
       board[0][0] == board[1][1] &&
       board[1][1] == board[2][2])
        return 1;
    if(board[0][2] != ' ' &&
       board[0][2] == board[1][1] &&
       board[1][1] == board[2][0])
        return 1;
    return 0;
}

int main(void) {
    initBoard();
    int row, col, moves = 0;
    char player = 'X';
    while(moves < 9) {
        printBoard();
        printf("玩家 %c,请输入行和列(0-2):", player);
        scanf("%d %d", &row, &col);
        if(row < 0 || row >= 3 || col < 0 || col >= 3 || board[row][col] != ' ') {
            printf("无效输入,请重试。\n");
            continue;
        }
        board[row][col] = player;
        moves++;
        if(checkWin()) {
            printBoard();
            printf("玩家 %c 获胜!\n", player);
            return 0;
        }
        player = (player == 'X') ? 'O' : 'X';
    }
    printBoard();
    printf("平局!\n");
    return 0;
}

说明:实现一个简易的 3x3 井字棋游戏。


杂项与拓展练习(例 91 ~ 100)

例 91 — 利用 clock() 实现简单计时器

#include <stdio.h>
#include <time.h>

int main(void) {
    clock_t start, end;
    start = clock();
    // 模拟耗时操作
    for(long i = 0; i < 100000000; i++);
    end = clock();
    double duration = (double)(end - start) / CLOCKS_PER_SEC;
    printf("耗时:%f 秒\n", duration);
    return 0;
}

说明:使用 clock() 函数测量程序运行时间。


例 92 — 递归生成 Gray Code 序列(打印 n 位 Gray Code)

#include <stdio.h>
#include <math.h>

void generateGray(int n, int num) {
    if(n == 0) {
        printf("%0*d\n", 1, num);
        return;
    }
    generateGray(n - 1, num);
    generateGray(n - 1, num ^ (1 << (n - 1)));
}

int main(void) {
    int n;
    printf("请输入 Gray Code 位数:");
    scanf("%d", &n);
    int total = pow(2, n);
    for (int i = 0; i < total; i++)
        generateGray(n, i);
    return 0;
}

说明:递归生成并打印 n 位 Gray Code 序列。


例 93 — 使用 qsort() 对结构体数组排序

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct {
    int id;
    char name[50];
} Person;

int compare(const void *a, const void *b) {
    return ((Person*)a)->id - ((Person*)b)->id;
}

int main(void) {
    Person people[3] = {{3, "Charlie"}, {1, "Alice"}, {2, "Bob"}};
    qsort(people, 3, sizeof(Person), compare);
    for (int i = 0; i < 3; i++)
        printf("ID: %d, Name: %s\n", people[i].id, people[i].name);
    return 0;
}

说明:利用标准库函数 qsort 对结构体数组按 id 进行排序。


例 94 — 使用 bsearch() 实现二分查找(查结构体数组)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct {
    int id;
    char name[50];
} Person;

int compare(const void *a, const void *b) {
    return ((Person*)a)->id - ((Person*)b)->id;
}

int main(void) {
    Person people[3] = {{1, "Alice"}, {2, "Bob"}, {3, "Charlie"}};
    int key = 2;
    Person target = {key, ""};
    Person *found = bsearch(&target, people, 3, sizeof(Person), compare);
    if(found)
        printf("找到: ID = %d, Name = %s\n", found->id, found->name);
    else
        printf("未找到\n");
    return 0;
}

说明:利用 bsearch 在已经排序的结构体数组中查找指定元素。


例 95 — 可变参数函数示例(自定义简单打印函数)

#include <stdio.h>
#include <stdarg.h>

void myPrint(const char *format, ...) {
    va_list args;
    va_start(args, format);
    vprintf(format, args);
    va_end(args);
}

int main(void) {
    myPrint("输出整型:%d, 浮点:%f, 字符串:%s\n", 10, 3.14, "Hello");
    return 0;
}

说明:使用 stdarg.h 实现可变参数函数,模拟 printf 部分功能。


例 96 — 实现自定义字符串分割(使用 strtok)

#include <stdio.h>
#include <string.h>

int main(void) {
    char str[256];
    printf("请输入一行文本:");
    fgets(str, sizeof(str), stdin);
    char *token = strtok(str, " ,.-\n");
    printf("分割结果:\n");
    while(token != NULL) {
        printf("%s\n", token);
        token = strtok(NULL, " ,.-\n");
    }
    return 0;
}

说明:利用 strtok() 函数分割字符串,演示字符串处理技巧。


例 97 — 打印系统环境变量(利用 getenv)

#include <stdio.h>
#include <stdlib.h>

int main(void) {
    char *path = getenv("PATH");
    if(path != NULL)
        printf("PATH = %s\n", path);
    else
        printf("获取 PATH 环境变量失败。\n");
    return 0;
}

说明:通过 getenv 获取并打印环境变量。


例 98 — 动态分配二维数组(矩阵)

#include <stdio.h>
#include <stdlib.h>

int main(void) {
    int rows, cols;
    printf("请输入行数和列数:");
    scanf("%d %d", &rows, &cols);
    int **matrix = malloc(rows * sizeof(int *));
    for (int i = 0; i < rows; i++)
        matrix[i] = malloc(cols * sizeof(int));
    // 初始化矩阵
    for (int i = 0; i < rows; i++)
        for (int j = 0; j < cols; j++)
            matrix[i][j] = i * cols + j;
    // 输出矩阵
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++)
            printf("%d ", matrix[i][j]);
        printf("\n");
    }
    for (int i = 0; i < rows; i++)
        free(matrix[i]);
    free(matrix);
    return 0;
}

说明:演示如何动态分配二维数组并释放内存。


例 99 — 条件编译和宏定义示例

#include <stdio.h>

#define DEBUG 1

int main(void) {
#ifdef DEBUG
    printf("调试模式开启\n");
#endif
    printf("程序运行中...\n");
    return 0;
}

说明:利用条件编译和宏定义控制调试信息输出。


例 100 — 内联函数示例(C99 inline 关键字)

#include <stdio.h>

inline int add(int a, int b) {
    return a + b;
}

int main(void) {
    int result = add(5, 3);
    printf("内联函数计算:%d\n", result);
    return 0;
}

说明:展示 inline 函数的基本用法,提示编译器内联扩展。


结语

本文提供了从基础语法、数组字符串操作、各类排序与查找算法、数据结构实现、递归与经典问题、指针与动态内存、文件 I/O 及位运算,再到实用算法和拓展练习的 100 个经典 C 语言例题
每个例题均给出完整的源码和简要说明,适合初学者练习和进阶者查漏补缺。希望读者能够通过这些实例,深入理解 C 语言的精髓与实际应用。
如果有任何问题或改进建议,欢迎在评论区交流讨论,共同进步!

祝大家编程愉快,码力不断提升!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值