C语言中的数组指针数组与函数指针数组
目录
- 一、引言
- 二、数组指针数组(Array of Pointers to Arrays)
- 1. 基本概念与语法
- 2.内存模型与初始化
- 3. 元素访问技巧
- 4. 数组指针数组的典型应用
- 三、函数指针数组(Array of Function Pointers)
- 1. 基本概念与语法
- 2.初始化与调用
- 3.函数指针数组的典型应用
- 四、数组指针数组与函数指针数组的区别
一、引言
在 C 语言的高级应用中,数组指针数组和函数指针数组是两个强大但容易混淆的概念。它们分别代表了 "存储数组指针的数组" 和 "存储函数指针的数组",在系统编程、嵌入式开发、游戏引擎等领域有着广泛的应用。本文将深入解析这两个概念的语法、应用场景及关键区别。
二、数组指针数组(Array of Pointers to Arrays)
1. 基本概念与语法
数组指针数组是一个数组,其元素都是指向数组的指针。这种数据结构常用于处理多维数组的集合或动态调整数组大小。
定义语法:
data_type (*array_name[size])[array_size];
data_type:指向的数组元素类型array_name:数组名称size:数组指针数组的大小array_size:每个指针指向的数组大小
// 声明:包含3个元素的数组,每个元素是指向int[4]的指针 int (*arrPtrArray[3])[4];
示例代码:
#include <stdio.h>
int main() {
int arr1[3] = {1, 2, 3};
int arr2[3] = {4, 5, 6};
int arr3[3] = {7, 8, 9};
// 定义数组指针数组
int (*arr_ptr_array[3])[3] = {&arr1, &arr2, &arr3};
// 访问数组元素
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
printf("%d ", (*arr_ptr_array[i])[j]);
}
printf("\n");
}
return 0;
}
2.内存模型与初始化
int matrix1[4] = {1,2,3,4};
int matrandroidix2[4] = {5,6,7,8};
int matrix3[4] = {9,10,11,12};
// 初始化数组指针数组
int (*arrayOfPtrs[3])[4] = {&matrix1, &matrix2, &matrix3};
内存布局:
栈内存: +---------------------+ | arrayOfPtrs[0] | --> 指向matrix1 (地址0x1000) +---------------------+ | arrayOfPtrs[1] | --> 指向matrix2 (地址0x1010) +---------------------+ | arrayOfPtrs[2] | --> 指向matrix3 (地址0x1020) +---------------------+ 堆/数据区: 0x1000: [1,2,3,4] // matrix1 0x1010: [5,6,7,8] // matrix2 0x1020: [9,10,11,12] // matrix3
3. 元素访问技巧
// 访问第2个矩阵的第3个元素
int val = (*arrayOfPtrs[1])[2]; // 获取7
// 遍历所有矩阵
for(int i=0; i<3; i++) {
printf("矩阵%d: ", i+1);
for(int j=0; j<4; j++) {
printf("%d ", (*arrayOfPtrs[i])[j]);
}
printf("\n");
}
4. 数组指针数组的典型应用
⑴. 动态二维数组管理
使用数组指针数组动态管理多个二维数组:
#include <stdio.h>
#include <stdlib.h>
int main() {
// 创建3个4x4的二维数组
int (*matrices[3])[4][4];
for (int i = 0; i < 3; i++) {
matrices[i] = (int (*)[4][4])malloc(sizeof(int[4][4]));
// 初始化二维数组
for (int j = 0; j < 4; j++) {
for (int k = 0; k < 4; k++) {
(*matrices[i])[j][k] = i * 16 + j * 4 + k;
}
}
}
// 释放内存
for (int i = 0; i < 3; i++) {
free(matrices[i]);
}
return 0;
}
⑵.多维度数据处理
在科学计算中,常用于处理多组实验数据:
// 假设有3组温度数据,每组10个测量值 float (*temperature_data[3])[10];
三、函数指针数组(Arhttp://www.devze.comray of Function Pointers)
1. 基本概念与语法
函数指针数组是一个数组,其元素都是指向函数的指针。这种数据结构常用于实现状态机、命令处理器或回调函数表。
定义语法:
return_type (*array_name[size])(parameter_list);
return_type:函数返回类型array_name:数组名称size:数组大小parameter_list:函数参数列表
// 声明:包含4个函数指针的数组 // 每个函数接受int返回void void (*funcArray[4])(int);
示例代码:
#include <stdio.h>
// 定义三个不同的函数
int add(int a, int b) { return a + b; }
int subtract(int a, int b) { return a - b; }
int multiply(int a, int b) { return a * b; }
int main() {
// 定义函数指针数组
int (*operations[3])(int, int) = {add, subtract, multiply};
// 通过函数指针数组调用函数
printf("3 + 5 = %d\n", operations[0](3, 5)); // 输出: 8
printf("3 - 5 = %d\n", operations[1](3, 5)); // 输出: -2
printf("3 * 5 = %d\n", operations[2](3, 5)); // 输出: 15
return 0;
}
2.初始化与调用
// 定义不同函数
void processA(int x) { printf("A处理: %d\n", x*2); }
void processB(int x) { printf("B处理: %d\n", x+5); }
void processC(int x) { printf("C处理: %d\n", x/2); }
// 初始化数组
void (*operations[3])(int) = {processA, processB, processC};
// 动态调用
int cmd = 0, value = 10;
while(1) {
printf("输入命令(0-2, 其他退出): ");
scanf("%d", &cmd);
if(cmd < 0 || cmd > 2) break;
operations[cmd](value); // 关键调用
}
内存布局:
代码区: 0x4000: processA 机器码 0x4100: processB 机器码 0x4200: processC 机器码 数据区: funcArray[0] = 0x4000 funcArray[1] js= 0x4100 funcArray[2] = 0x4200
3.函数指针数组的典型应用
⑴.状态机实现
使用函数指针数组实现简单的状态机:
#include <stdio.h>
// 定义状态处理函数类型
typedef void (*StateHandler)();
// 状态处理函数
void state_idle() { printf("空闲状态\n"); }
void state_running() { printf("运行状态\n"); }
void state_error() { printf("错误状态\n"); }
int main() {
// 状态函数指针数组
StateHandler states[3] = {state_idle, state_running, state_error};
// 当前状态
int current_state = 1;
// 执行当前状态处理函数
states[current_state](); // 输出: 运行状态
return 0;
}
⑵.命令行解析器
使用函数指针数组实现命令行解析器:
#include <stdio.h>
#include <string.h>
// 命令处理函数类型
typedef void (*CommandHandler)();
// 命令处理函数
void cmd_help() { printf("显示帮助信息\n"); }
void cmd_quit() { printf("退出程序\n"); }
void cmd_list() { printf("列出文件\n"); }
编程// 命令结构
struct Command {
const char* name;
CommandHandler handler;
};
int main() {
// 命令表
struct Command commands[] = {
{"help", cmd_help},
{"quit", cmd_quit},
{"list", cmd_list}
};
int num_commands = sizeof(commands) / sizeof(commands[0]);
char input[20];
printf("输入命令: ");
scanf("%s", input);
js
// 查找并执行命令
for (int i = 0; i < num_commands; i++) {
if (strcmp(input, commands[i].name) == 0) {
commands[i].handler();
break;
}
}
return 0;
}
四、数组指针数组与函数指针数组的区别
| 特性 | 数组指针数组 | 函数指针数组 |
|---|---|---|
| 本质 | 存储数组指针的数组 | 存储函数指针的数组 |
| 语法 | data_type (*arr[size])[array_size] | return_type (*arr[size])(params) |
| 元素类型 | 指向数组的指针 | 指向函数的指针 |
| 典型应用 | 动态多维数组管理、科学计算 | 状态机、命令解析器、回调函数表 |
| 访问方式 | (*arr[i])[j] | arr[i](args) |
到此这篇关于C语言中的数组指针数组与函数指针数组的文章就介绍到这了,更多相关C语言数组指针数组与函数指针数组内容请搜索编程客栈(www.devze.com)以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程客栈(www.devze.com)!
加载中,请稍侯......
精彩评论