C语言Day05笔记

1笔记

一、函数基础概念

1. 函数定义

  • 作用:将代码模块化,实现代码复用逻辑封装分层设计

  • 核心特点

    • 每个函数完成独立任务。

    • 通过参数传递数据,通过返回值输出结果。

    • 函数之间通过调用关系协作。


二、函数语法

1. 函数定义格式

返回类型 函数名(参数列表) {
    // 函数体
    return 返回值;  // 若返回类型为 void,可省略 return
}
示例:加法函数
int add(int a, int b) {
    return a + b;
}

2. 函数声明(原型)

  • 作用:告诉编译器函数的存在性(用于分离式编译)。

  • 格式返回类型 函数名(参数类型列表);
    (参数名可省略,但建议保留以提高可读性)

示例:
int add(int, int);  // 声明
// 或
int add(int a, int b);  // 推荐写法

三、参数传递机制

1. 值传递(默认行为)

  • 规则:函数内部操作的是参数的副本,不影响原始数据。

  • 示例

    void swap(int x, int y) {
        int temp = x;
        x = y;
        y = temp;  // 仅交换副本,不影响外部变量
    }

2. 指针传递(模拟“引用传递”)

  • 规则:通过指针直接操作原始数据的内存地址。

  • 示例

    void swap(int *x, int *y) {
        int temp = *x;
        *x = *y;
        *y = temp;  // 实际修改外部变量
    }

3. 数组作为参数

  • 特点:数组名退化为指针,传递的是数组首地址。

  • 示例

    void printArray(int arr[], int size) {  // 等价于 int *arr
        for (int i = 0; i < size; i++) {
            printf("%d ", arr[i]);
        }
    }


四、返回值

1. 基本规则

  • 返回类型:必须与函数声明一致(void 表示无返回值)。

  • 返回值限制

    • 可以返回基本类型(intfloat 等)、结构体、指针。

    • 不可返回局部变量的地址(函数结束局部变量被销毁,导致悬垂指针)。

2. 多返回值模拟

  • 方法 1:通过指针参数修改外部变量。

  • 方法 2:返回结构体(包含多个数据)。


五、作用域与生命周期

1. 局部变量

  • 作用域:仅在函数内部有效。

  • 生命周期:函数调用时创建,函数结束时销毁。

2. 全局变量

  • 作用域:从定义位置到文件末尾。

  • 生命周期:程序运行期间始终存在。

3. 静态局部变量(static

  • 特点

    • 作用域仍为函数内部。

    • 生命周期延长至程序结束(值在多次调用间保留)。

  • 示例

    void counter() {
        static int count = 0;  // 只初始化一次
        count++;
        printf("Count: %d\n", count);
    }


六、递归函数

1. 核心条件

  • 基线条件(Base Case):递归终止条件。

  • 递归条件(Recursive Case):问题分解为更小规模的同类问题。

2. 示例:阶乘计算

int factorial(int n) {
    if (n <= 1) {  // 基线条件
        return 1;
    } else {       // 递归条件
        return n * factorial(n - 1);
    }
}

3. 注意事项

  • 栈溢出风险:递归深度过大可能导致栈空间耗尽。

  • 效率问题:递归可能比循环更耗资源(函数调用开销)。

2.作业

1.可变参实现my_printf

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

// 自定义简化版 printf 函数
void my_printf(const char *format, ...) {
    va_list args;          // 定义可变参数列表
    va_start(args, format); // 初始化参数列表

    while (*format != '\0') {  // 遍历格式字符串
        if (*format == '%') {  // 遇到格式符
            format++;  // 跳过 '%'

            // 根据格式符处理不同类型
            switch (*format) {
                case 'd': {  // 处理整数
                    int num = va_arg(args, int);
                    printf("%d", num);
                    break;
                }
                case 'f': {  // 处理浮点数(默认保留两位小数)
                    double num = va_arg(args, double);
                    printf("%.2f", num);
                    break;
                }
                case 's': {  // 处理字符串
                    char *str = va_arg(args, char*);
                    printf("%s", str);
                    break;
                }
                case 'c': {  // 处理字符
                    char ch = (char)va_arg(args, int); // char 会被提升为 int
                    printf("%c", ch);
                    break;
                }
                case '%': {  // 输出 '%' 自身
                    putchar('%');
                    break;
                }
                default: {   // 未知格式符直接输出
                    putchar('%');
                    putchar(*format);
                }
            }
        } else {  // 普通字符直接输出
            putchar(*format);
        }
        format++;  // 继续下一个字符
    }

    va_end(args);  // 清理参数列表
}

int main() {
    // 测试
    my_printf("整数:%d,浮点数:%f,字符:%c,字符串:%s\n",50,2.1,'a',"hahaha");
   
    return 0;
}

 

2.回调函数结构体排序

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


// 定义学生结构体
typedef struct {
    char name[50];
    int score;
} Student;

// 比较函数:按分数降序排序
int compareByScore(const void *a, const void *b) {
    const Student *s1 = (const Student*)a;
    const Student *s2 = (const Student*)b;
    return s2->score - s1->score;  // 降序:大值在前
}

// 打印学生数组
void printStudents(const Student *students, int size) {
    for (int i = 0; i < size; i++) {
        printf("Name: %-10s | Score: %3d\n", students[i].name, students[i].score);
    }
    printf("--------------------------\n");
}

int main() {
    // 初始化学生数组
    Student students[] = {
        {"张三", 85},
        {"李四", 92},
        {"小明", 78},
        {"小红", 92}  // 分数相同,测试稳定性
    };
    int size = sizeof(students) / sizeof(students[0]);

    printf("Original order:\n");
    printStudents(students, size);

    // 按分数降序排序
    qsort(students, size, sizeof(Student), compareByScore);
    printf("按分数降序(排序):\n");
    printStudents(students, size);

    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值