C语言函数知识点大全(四)

简介: 教程来源 http://htnus.cn/category/artificial-intelligence.html 本文系统讲解C语言函数高级特性:回调函数实现异步处理与自定义排序;setjmp/longjmp实现非局部跳转;函数与动态内存管理技巧;以及单一职责、命名规范、参数控制等最佳实践,涵盖常见错误与规避方法。

十、函数的高级应用

10.1 回调函数

#include <stdio.h>

// 回调函数类型
typedef void (*Callback)(int);

// 执行任务并在完成后调用回调
void processData(int* data, int size, Callback callback) {
    for (int i = 0; i < size; i++) {
        data[i] = data[i] * 2;  // 处理数据
        callback(data[i]);       // 调用回调
    }
}

// 回调函数实现
void printValue(int value) {
    printf("%d ", value);
}

void logValue(int value) {
    // 可以记录日志、写入文件等
}

// 排序回调
typedef int (*CompareFunc)(int, int);

void bubbleSort(int arr[], int size, CompareFunc compare) {
    for (int i = 0; i < size - 1; i++) {
        for (int j = 0; j < size - i - 1; j++) {
            if (compare(arr[j], arr[j + 1]) > 0) {
                int temp = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = temp;
            }
        }
    }
}

int ascending(int a, int b) {
    return a - b;
}

int descending(int a, int b) {
    return b - a;
}

int main() {
    int data[] = {1, 2, 3, 4, 5};
    printf("处理结果: ");
    processData(data, 5, printValue);
    printf("\n");

    int numbers[] = {5, 2, 8, 1, 9, 3};
    int size = sizeof(numbers) / sizeof(numbers[0]);

    bubbleSort(numbers, size, ascending);
    printf("升序: ");
    for (int i = 0; i < size; i++) {
        printf("%d ", numbers[i]);
    }
    printf("\n");

    bubbleSort(numbers, size, descending);
    printf("降序: ");
    for (int i = 0; i < size; i++) {
        printf("%d ", numbers[i]);
    }
    printf("\n");

    return 0;
}

10.2 函数跳转(setjmp/longjmp)

#include <stdio.h>
#include <setjmp.h>

jmp_buf env;

void second(void) {
    printf("second() 开始\n");
    longjmp(env, 1);  // 跳回setjmp位置
    printf("second() 结束\n");  // 不会执行
}

void first(void) {
    printf("first() 开始\n");
    second();
    printf("first() 结束\n");  // 不会执行
}

int main() {
    if (setjmp(env) == 0) {
        printf("正常执行路径\n");
        first();
    } else {
        printf("从longjmp跳转回来\n");
    }

    printf("程序继续执行\n");
    return 0;
}

十一、函数与内存管理

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

// 在函数内部分配内存并返回
char* createString(const char* source) {
    char* str = (char*)malloc(strlen(source) + 1);
    if (str != NULL) {
        strcpy(str, source);
    }
    return str;
}

// 在函数内部修改指针
void allocateArray(int** arr, int size) {
    *arr = (int*)malloc(size * sizeof(int));
    if (*arr != NULL) {
        for (int i = 0; i < size; i++) {
            (*arr)[i] = i + 1;
        }
    }
}

// 错误示例:返回局部变量的地址
int* badFunction(void) {
    int local = 100;
    return &local;  // 危险!返回栈变量的地址
}

// 正确示例:返回静态变量的地址
int* goodFunction(void) {
    static int value = 100;
    return &value;  // 安全:静态变量生命周期是整个程序
}

int main() {
    char* str = createString("Hello, World!");
    if (str != NULL) {
        printf("字符串: %s\n", str);
        free(str);
    }

    int* arr = NULL;
    allocateArray(&arr, 10);
    if (arr != NULL) {
        for (int i = 0; i < 10; i++) {
            printf("%d ", arr[i]);
        }
        printf("\n");
        free(arr);
    }

    int* p = goodFunction();
    printf("静态变量: %d\n", *p);

    return 0;
}

十二、最佳实践

12.1 函数设计原则

// 1. 单一职责:一个函数只做一件事
// 不好
void processUserData(char* name, int age, char* email) {
    // 验证、保存、发送邮件混在一起
}

// 好
int validateName(const char* name);
int validateAge(int age);
int validateEmail(const char* email);
void saveUser(const char* name, int age, const char* email);
void sendWelcomeEmail(const char* email);

// 2. 函数命名规范
int calculateTotal(void);        // 动词开头
int isEven(int num);             // 判断函数用is/has/can开头
void setValue(int val);          // setter
int getValue(void);              // getter

// 3. 函数长度控制
// 一个函数建议不超过50-100行

// 4. 参数数量控制
// 建议不超过3-4个参数
// 参数过多时使用结构体封装

typedef struct {
    char name[50];
    int age;
    char email[100];
    char phone[20];
} UserInfo;

void createUser(const UserInfo* info);

// 5. 返回值规范
// 返回状态码表示成功/失败
int doSomething(void) {
    // 成功返回0,失败返回错误码
    return 0;
}

// 返回指针时,失败返回NULL
int* createArray(int size) {
    if (size <= 0) return NULL;
    return (int*)malloc(size * sizeof(int));
}

12.2 常见错误与避免

// 错误1:返回局部变量地址
int* wrong1(void) {
    int local = 10;
    return &local;  // 错误
}

// 错误2:数组参数大小信息丢失
void wrong2(int arr[]) {
    // sizeof(arr) 是指针大小,不是数组大小
    int size = sizeof(arr);  // 错误
}

// 正确:传递大小参数
void correct2(int arr[], int size) {
    for (int i = 0; i < size; i++) {
        // ...
    }
}

// 错误3:忘记检查malloc返回值
void wrong3(void) {
    int* p = (int*)malloc(100 * sizeof(int));
    *p = 100;  // 危险:可能p为NULL
}

// 正确:检查返回值
void correct3(void) {
    int* p = (int*)malloc(100 * sizeof(int));
    if (p != NULL) {
        *p = 100;
        free(p);
    }
}

C语言函数是C程序设计的核心,从基本的函数定义到复杂的函数指针,从简单的递归到高级的回调机制,C语言的函数体系为开发者提供了强大而灵活的编程能力。本文系统性地梳理了C语言函数的核心知识点,帮助开发者建立完整的知识体系。
来源:
http://htnus.cn/

相关文章
|
4月前
|
安全 Java API
Java日期处理完全指南(新手也能轻松掌握的Java时间格式化与日期API教程)
教程来源https://www.vpshk.cn/本文介绍Java 8引入的java.time包,详解LocalDateTime、LocalDate等类的使用,涵盖获取当前时间、格式化、解析字符串及日期运算,助你轻松掌握现代Java日期处理方法,适合初学者快速上手。
|
5天前
|
JavaScript API 网络安全
2026年4月阿里云轻量服务器部署OpenClaw保姆级教程(千问+Coding Plan API配置)
OpenClaw(曾用名Clawdbot、Moltbot,社区昵称“小龙虾”)是一款开源、本地优先、可自托管的AI智能体框架,核心价值在于让大模型从“被动问答”升级为“主动执行”——不仅能理解自然语言指令,还能直接在服务器上完成文件管理、终端命令执行、API调用、多步骤任务编排等操作,彻底打通“指令→规划→执行”全链路。
206 4
|
8天前
|
人工智能 机器人 Linux
OpenClaw(Clawdbot)阿里云计算巢部署+企业微信机器人搭建|零代码命令速通+常见问题全解
2026年,OpenClaw(原Clawdbot)凭借轻量化部署、多平台接入与灵活的Skill扩展能力,成为企业搭建专属AI助手的首选工具。对于新手而言,阿里云计算巢是部署OpenClaw的最优选择——全程可视化、一键部署、无需复杂环境配置,搭配企业微信可快速搭建能在企业内部群聊、单聊中响应消息、执行指令、自动处理任务的AI机器人,满足企业内部沟通、信息查询、流程自动化等需求。
214 4
|
人工智能 计算机视觉
港科大这个AI突破,让大模型学会“偷懒”了
多模态大模型推理效率低?港科大最新研究MoDES,让AI学会“偷懒”——跳过88%冗余专家,保住97%性能,推理速度翻倍。这项被CVPR接收的突破,正在让大模型从“拼参数”转向“拼效率”。
116 0
港科大这个AI突破,让大模型学会“偷懒”了
|
7天前
|
网络协议 数据可视化 应用服务中间件
如何申请免费ssl证书以及自动续期
本文详解SSL证书申请与自动续期方案:推荐可视化工具CertGo(桌面端)和轻量脚本acme.sh。涵盖阿里云DNS配置、FreeSSL账号绑定(EAB)、多域名/泛域名申请、Nginx部署及自动续签,零依赖、易上手,助你轻松实现HTTPS全站加密。(239字)
185 3
|
10天前
|
XML 前端开发 开发者
CSS学习知识点大全(一)
教程来源 https://app-a7illrp9pngh.appmiaoda.com/ 梳理CSS核心知识:从基础语法、四大引入方式,到选择器(基础/组合/属性/伪类/伪元素)及优先级规则;详解盒模型(标准/怪异)、属性设置与外边距折叠。助力新手构建完整体系,也为开发者提供深度参考。
|
24天前
|
Arthas 人工智能 Java
我们做了比你更懂 Java 的 AI-Agent -- Arthas Agent
Arthas Agent 是基于阿里开源Java诊断工具Arthas的AI智能助手,支持自然语言提问,自动匹配排障技能、生成安全可控命令、循证推进并输出结构化报告,大幅降低线上问题定位门槛。
753 64
我们做了比你更懂 Java 的 AI-Agent -- Arthas Agent
|
12天前
|
SQL Oracle 关系型数据库
Oracle数据库学习知识点(一)
教程来源 https://app-ah8jla8z2m81.appmiaoda.com 系统梳理Oracle数据库核心知识,涵盖安装配置、体系结构、SQL基础、PL/SQL编程等关键内容,兼顾初学者入门与DBA/开发者进阶需求,助力构建完整技术体系。

热门文章

最新文章