嵌入式学习 C语言-指针(2)
函数指针是指向函数的指针变量。函数名本身就代表函数的入口地址,我们可以定义一个指针变量来存储这个地址。语法格式:返回值类型 (*指针变量名)(参数列表);示例:// 定义函数指针// 通过函数指针调用函数// 等价于 add(3, 5)
深入理解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语言中最强大也最危险的工具,正确使用指针可以写出高效灵活的程序,而错误使用则可能导致难以调试的问题。建议通过大量练习来掌握指针的各种用法。
openvela 操作系统专为 AIoT 领域量身定制,以轻量化、标准兼容、安全性和高度可扩展性为核心特点。openvela 以其卓越的技术优势,已成为众多物联网设备和 AI 硬件的技术首选,涵盖了智能手表、运动手环、智能音箱、耳机、智能家居设备以及机器人等多个领域。
更多推荐


所有评论(0)