Skip to content

functions.c

文件信息

  • 📄 原文件:01_functions.c
  • 🔤 语言:c

完整代码

c
// ============================================================
//                      函数
// ============================================================
// C 函数:返回类型 函数名(参数列表) { 函数体 }
// 函数原型(声明)告知编译器函数签名
// 函数指针:C 中实现回调和策略模式的核心机制

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>   // 需链接 -lm

// ============================================================
//                      函数声明(原型)
// ============================================================
// 函数原型让编译器在调用前知道函数签名
// 通常放在头文件(.h)中

int add(int a, int b);
double circle_area(double radius);
void swap(int *a, int *b);
int factorial(int n);
int fibonacci(int n);

// 函数指针类型别名(增强可读性)
typedef int (*BinaryOp)(int, int);
typedef int (*Comparator)(const void *, const void *);

// ============================================================
//                      函数定义
// ============================================================

// ----------------------------------------------------------
// 1. 基本函数
// ----------------------------------------------------------
int add(int a, int b) {
    return a + b;
}

// void 函数(无返回值)
void greet(const char *name) {
    printf("你好,%s\n", name);
}

// 返回 double
double circle_area(double radius) {
    return 3.14159265358979 * radius * radius;
}

// ----------------------------------------------------------
// 2. 参数传递:值传递 vs 指针传递
// ----------------------------------------------------------
// 【重要】C 函数参数默认是值传递(副本),修改不影响原变量

void try_swap_by_value(int a, int b) {
    int temp = a;
    a = b;
    b = temp;
    // 只交换了局部副本,原变量不变
}

// 指针传递:传递地址,可以修改原变量
void swap(int *a, int *b) {
    int temp = *a;  // 解引用:获取地址处的值
    *a = *b;
    *b = temp;
}

// 通过指针返回多个值
void min_max(const int *arr, int len, int *min, int *max) {
    *min = *max = arr[0];
    for (int i = 1; i < len; i++) {
        if (arr[i] < *min) *min = arr[i];
        if (arr[i] > *max) *max = arr[i];
    }
}

// ----------------------------------------------------------
// 3. 递归函数
// ----------------------------------------------------------
int factorial(int n) {
    if (n <= 1) return 1;
    return n * factorial(n - 1);
}

int fibonacci(int n) {
    if (n <= 1) return n;
    return fibonacci(n - 1) + fibonacci(n - 2);
}

// 尾递归(编译器可能优化为循环,避免栈溢出)
int factorial_tail(int n, int acc) {
    if (n <= 1) return acc;
    return factorial_tail(n - 1, n * acc);
}

// ----------------------------------------------------------
// 4. 可变参数函数
// ----------------------------------------------------------
#include <stdarg.h>  // va_list, va_start, va_arg, va_end

// 实现简单的 printf 风格函数
int my_sum(int count, ...) {
    va_list args;
    va_start(args, count);  // 从 count 后开始

    int sum = 0;
    for (int i = 0; i < count; i++) {
        sum += va_arg(args, int);  // 逐个取出参数
    }

    va_end(args);  // 必须调用,清理
    return sum;
}

// ----------------------------------------------------------
// 5. 内联函数(C99,避免函数调用开销)
// ----------------------------------------------------------
static inline int max(int a, int b) {
    return (a > b) ? a : b;
}

static inline int min(int a, int b) {
    return (a < b) ? a : b;
}

// ----------------------------------------------------------
// 6. 静态函数(internal linkage,只在本文件可见)
// ----------------------------------------------------------
static double power(double base, int exp) {
    double result = 1.0;
    for (int i = 0; i < exp; i++)
        result *= base;
    return result;
}

// ----------------------------------------------------------
// 7. 函数指针
// ----------------------------------------------------------
int subtract(int a, int b) { return a - b; }
int multiply(int a, int b) { return a * b; }

// 接受函数指针作为参数(高阶函数)
int apply(int a, int b, BinaryOp op) {
    return op(a, b);
}

// 函数指针数组(分发表/跳转表)
int dispatch(int op, int a, int b) {
    BinaryOp ops[] = { add, subtract, multiply };
    if (op < 0 || op >= 3) return -1;
    return ops[op](a, b);
}

// 回调函数示例:排序比较器
int compare_asc(const void *a, const void *b) {
    return (*(int*)a - *(int*)b);
}

int compare_desc(const void *a, const void *b) {
    return (*(int*)b - *(int*)a);
}

// ============================================================
//                      主函数
// ============================================================
int main(void) {
    printf("=== 基本函数 ===\n");

    printf("add(3, 5) = %d\n", add(3, 5));
    greet("世界");
    printf("circle_area(5.0) = %.2f\n", circle_area(5.0));

    // 值传递 vs 指针传递
    printf("\n=== 参数传递 ===\n");
    int x = 10, y = 20;
    printf("交换前: x=%d, y=%d\n", x, y);

    try_swap_by_value(x, y);
    printf("值传递后: x=%d, y=%d(未改变)\n", x, y);

    swap(&x, &y);  // 传递地址
    printf("指针传递后: x=%d, y=%d(已交换)\n", x, y);

    // 通过指针返回多个值
    int arr[] = {5, 2, 8, 1, 9, 3};
    int lo, hi;
    min_max(arr, 6, &lo, &hi);
    printf("数组最小值=%d, 最大值=%d\n", lo, hi);

    // 递归
    printf("\n=== 递归 ===\n");
    for (int i = 0; i <= 10; i++) {
        printf("%d! = %d\n", i, factorial(i));
    }

    printf("\n斐波那契: ");
    for (int i = 0; i <= 10; i++) {
        printf("%d ", fibonacci(i));
    }
    printf("\n");

    printf("尾递归 10! = %d\n", factorial_tail(10, 1));

    // 可变参数
    printf("\n=== 可变参数 ===\n");
    printf("my_sum(3, 1,2,3) = %d\n", my_sum(3, 1, 2, 3));
    printf("my_sum(5, 1,2,3,4,5) = %d\n", my_sum(5, 1, 2, 3, 4, 5));

    // 内联函数
    printf("\n=== 内联函数 ===\n");
    printf("max(7, 3) = %d\n", max(7, 3));
    printf("min(7, 3) = %d\n", min(7, 3));
    printf("power(2, 10) = %.0f\n", power(2, 10));

    // 函数指针
    printf("\n=== 函数指针 ===\n");

    BinaryOp op = add;
    printf("op(3, 4) = %d\n", op(3, 4));

    op = subtract;
    printf("op(10, 3) = %d\n", op(10, 3));

    printf("apply(6, 7, multiply) = %d\n", apply(6, 7, multiply));

    // 分发表
    printf("dispatch(0, 5, 3) = %d(加法)\n", dispatch(0, 5, 3));
    printf("dispatch(1, 5, 3) = %d(减法)\n", dispatch(1, 5, 3));
    printf("dispatch(2, 5, 3) = %d(乘法)\n", dispatch(2, 5, 3));

    // qsort 使用回调
    printf("\n=== qsort 回调 ===\n");
    int nums[] = {5, 2, 8, 1, 9, 3, 7, 4, 6};
    int len = sizeof(nums) / sizeof(nums[0]);  // 数组长度

    qsort(nums, len, sizeof(int), compare_asc);
    printf("升序: ");
    for (int i = 0; i < len; i++) printf("%d ", nums[i]);
    printf("\n");

    qsort(nums, len, sizeof(int), compare_desc);
    printf("降序: ");
    for (int i = 0; i < len; i++) printf("%d ", nums[i]);
    printf("\n");

    printf("\n=== 函数演示完成 ===\n");
    return 0;
}

💬 讨论

使用 GitHub 账号登录后即可参与讨论

基于 MIT 许可发布