C语言中的数组指针数组与函数指针数组

 更新时间:2025年06月29日 15:24:03   作者:星猫245  
数组指针数组和函数指针数组是两个强大但容易混淆的概念,下面就来介绍一下C语言中的数组指针数组与函数指针数组的区别,具有一定的参考价值,感兴趣的可以了解一下

一、引言

在 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 matrix2[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];

三、函数指针数组(Array 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] = 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);
    
    // 查找并执行命令
    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语言数组指针数组与函数指针数组内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家! 

相关文章

  • C++流程控制中用于跳转的return和goto语句学习教程

    C++流程控制中用于跳转的return和goto语句学习教程

    这篇文章主要介绍了C++流程控制中用于跳转的return和goto语句学习教程,是C++入门学习中的基础知识,需要的朋友可以参考下
    2016-01-01
  • C语言关于二叉树中堆的创建和使用整理

    C语言关于二叉树中堆的创建和使用整理

    大家好,这里是针对二叉树中堆结构的顺序储存,整理出来一篇博客供我们一起复习和学习,如果文章中有理解不当的地方,还希望朋友们在评论区指出,我们相互学习,共同进步
    2022-08-08
  • c++引用传参和指针传参的区别及说明

    c++引用传参和指针传参的区别及说明

    这篇文章主要介绍了c++引用传参和指针传参的区别及说明,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-01-01
  • Qt6 QML实现DateTimePicker组件的示例代码

    Qt6 QML实现DateTimePicker组件的示例代码

    本文展示了基于Qt6.10实现的DateTimePicker时间日期选择器组件,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2025-12-12
  • 使用C语言实现动态数组Vector

    使用C语言实现动态数组Vector

    这篇文章主要为大家详细介绍了使用C语言实现动态数组Vector的相关知识,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2024-01-01
  • 详解C++ 智能指针的删除器

    详解C++ 智能指针的删除器

    标准库为智能指针提供了两个默认版本的删除器,可简化智能指针的代码编写,这篇文章主要介绍了C++智能指针的删除器的相关知识,需要的朋友可以参考下
    2025-05-05
  • C语言实现员工工资管理系统

    C语言实现员工工资管理系统

    这篇文章主要为大家详细介绍了C语言实现员工工资管理系统,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-02-02
  • C++ std::chrono库使用示例(实现C++ 获取日期,时间戳,计时等功能)

    C++ std::chrono库使用示例(实现C++ 获取日期,时间戳,计时等功能)

    std::chrono是C++标准库中的一个组件,用于表示和处理时间,这篇文章主要介绍了C++ std::chrono库使用指南(实现C++ 获取日期,时间戳,计时等功能),需要的朋友可以参考下
    2023-06-06
  • C++实现多项式相乘

    C++实现多项式相乘

    这篇文章主要介绍了C++实现多项式相乘方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-07-07
  • Matlab绘制雨云图的方法详解

    Matlab绘制雨云图的方法详解

    这篇文章主要介绍了如何利用Matlab实现雨云图的绘制,文中的示例代码讲解详细,对我们学习Matlab有一定的帮助,需要的可以参考一下
    2022-05-05

最新评论