深入理解C语言指针(下):函数指针与高级应用

在上一篇文章中,我们介绍了指针的基础知识、指针与数组、字符串的关系。本文将继续深入探讨指针的高级应用,包括函数指针、动态内存管理以及多级指针等内容。

一、函数指针

1.1 什么是函数指针?

函数指针是指向函数的指针变量。函数名本身就代表函数的入口地址,我们可以定义一个指针变量来存储这个地址。

1.2 函数指针的定义

语法格式:

返回值类型 (*指针变量名)(参数列表);

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

// 定义函数指针
int (*pfunc)(int, int) = add;

// 通过函数指针调用函数
int result = pfunc(3, 5);  // 等价于 add(3, 5)
 

1.3 函数指针的应用:回调函数

回调函数是一种通过函数指针调用的函数,常用于实现灵活的编程接口。

示例:实现计算器的四则运算

#include <stdio.h>

// 定义四种运算函数
int add(int a, int b) { return a + b; }
int sub(int a, int b) { return a - b; }
int mul(int a, int b) { return a * b; }
int div(int a, int b) { return a / b; }

// 回调函数处理器
void processData(int a, int b, int (*pfunc)(int, int)) {
    printf("Result: %d\n", pfunc(a, b));
}

int main() {
    int x = 10, y = 5;
    
    processData(x, y, add);  // 输出15
    processData(x, y, sub);  // 输出5
    processData(x, y, mul);  // 输出50
    processData(x, y, div);  // 输出2
    
    return 0;
}
 

1.4 函数指针数组

我们可以创建函数指针数组来实现更灵活的函数调用:

int (*operations[4])(int, int) = {add, sub, mul, div};

// 使用函数指针数组
for(int i = 0; i < 4; i++) {
    printf("Operation %d result: %d\n", i, operations[i](10, 5));
}
 

 二、动态内存管理

2.1 malloc和free函数

C语言提供了动态内存分配的函数:


void *malloc(size_t size);  // 申请内存
void free(void *ptr);       // 释放内存
 

2.2 动态内存使用示例


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

int main() {
    // 动态申请10个int的空间
    int *arr = (int *)malloc(10 * sizeof(int));
    if(arr == NULL) {
        printf("Memory allocation failed!\n");
        return 1;
    }
    
    // 初始化数组
    for(int i = 0; i < 10; i++) {
        arr[i] = i + 1;
    }
    
    // 计算累加和
    int sum = 0;
    for(int i = 0; i < 10; i++) {
        sum += arr[i];
    }
    printf("Sum: %d\n", sum);
    
    // 释放内存
    free(arr);
    
    return 0;
}
 

2.3 注意事项

1. 每次malloc后都要检查返回值是否为NULL
2. 使用完内存后要及时free
3. 不要重复free同一块内存
4. 不要访问已经free的内存

 三、多级指针

3.1 二级指针

二级指针是指向指针的指针:


int a = 10;
int *p = &a;     // 一级指针
int **pp = &p;   // 二级指针

// 通过二级指针访问a的值
printf("%d\n", **pp);  // 输出10
 

3.2 多级指针的应用

多级指针常用于处理指针数组:


char *strs[] = {"hello", "world", "china"};
char **p = strs;  // 二级指针指向指针数组

for(int i = 0; i < 3; i++) {
    printf("%s\n", *(p + i));  // 等价于 strs[i]
}
 

四、main函数参数

main函数可以接收命令行参数:


int main(int argc, char *argv[]) {
    // argc: 参数个数
    // argv: 参数字符串数组
    
    printf("Program name: %s\n", argv[0]);
    printf("Argument count: %d\n", argc);
    
    for(int i = 1; i < argc; i++) {
        printf("Argument %d: %s\n", i, argv[i]);
    }
    
    return 0;
}
 

五、综合练习

5.1 使用qsort排序字符串数组


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

// 比较函数
int compare(const void *a, const void *b) {
    return strcmp(*(const char **)a, *(const char **)b);
}

int main() {
    char *words[] = {"banana", "apple", "orange", "grape", "pear"};
    int count = sizeof(words) / sizeof(words[0]);
    
    // 排序
    qsort(words, count, sizeof(char *), compare);
    
    // 输出结果
    for(int i = 0; i < count; i++) {
        printf("%s\n", words[i]);
    }
    
    return 0;
}
 

5.2 动态创建二维数组


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

int main() {
    int rows = 3, cols = 4;
    
    // 动态申请二维数组
    int **arr = (int **)malloc(rows * sizeof(int *));
    for(int i = 0; i < rows; i++) {
        arr[i] = (int *)malloc(cols * sizeof(int));
    }
    
    // 初始化
    for(int i = 0; i < rows; i++) {
        for(int j = 0; j < cols; j++) {
            arr[i][j] = i * cols + j + 1;
        }
    }
    
    // 打印
    for(int i = 0; i < rows; i++) {
        for(int j = 0; j < cols; j++) {
            printf("%2d ", arr[i][j]);
        }
        printf("\n");
    }
    
    // 释放内存
    for(int i = 0; i < rows; i++) {
        free(arr[i]);
    }
    free(arr);
    
    return 0;
}
 

六、总结

1. 函数指针:指向函数的指针,用于实现回调等高级功能
2. 动态内存管理:使用malloc/free进行堆内存的申请和释放
3. 多级指针:处理指针数组等复杂数据结构
4. main函数参数:处理命令行输入

int main(int argc,const char &argv[])

@argc 表示 —— 命令行参数的个数

@argv 表示 —— 存放着命令行字符串的指针数组

指针是C语言中最强大也最危险的工具,正确使用指针可以写出高效灵活的程序,而错误使用则可能导致难以调试的问题。建议通过大量练习来掌握指针的各种用法。

Logo

openvela 操作系统专为 AIoT 领域量身定制,以轻量化、标准兼容、安全性和高度可扩展性为核心特点。openvela 以其卓越的技术优势,已成为众多物联网设备和 AI 硬件的技术首选,涵盖了智能手表、运动手环、智能音箱、耳机、智能家居设备以及机器人等多个领域。

更多推荐