C 语言从 0 入门(二十)|指针进阶:指针数组、数组指针与函数指针

大家好,我是网域小星球。

前面我们学过了指针基础、指针与数组的关系。但在进阶语法、笔试面试和实际项目里,经常会遇到三个长得很像、含义却完全不同的概念,很多人学到这里直接混淆:指针数组、数组指针、函数指针

它们长得像、用法不同、坑点密集。本篇用最清晰的对比 + 案例,一次性讲透,全程 VS2022 可直接运行。

目录

一、本章学习目标

二、先破局:一句话分清两个易混概念

三、数组指针(指向数组的指针)

[1. 定义](#1. 定义)

[2. 用途:指向二维数组](#2. 用途:指向二维数组)

四、指针数组(存放指针的数组)

[1. 定义](#1. 定义)

[2. 最常用场景:多字符串管理](#2. 最常用场景:多字符串管理)

[五、数组指针 vs 指针数组 对比表](#五、数组指针 vs 指针数组 对比表)

六、函数指针(指向函数的指针)

[1. 什么是函数指针?](#1. 什么是函数指针?)

[2. 定义格式](#2. 定义格式)

[3. 最简单使用示例](#3. 最简单使用示例)

[4. 实战用途:菜单跳转 / 回调函数](#4. 实战用途:菜单跳转 / 回调函数)

七、高频易错点

八、本章核心总结

下期预告


一、本章学习目标

  1. 分清 数组指针指针数组,不再混淆
  2. 掌握二维数组与数组指针的关系
  3. 理解 函数指针 是什么、怎么定义、怎么用
  4. 学会用函数指针实现回调、简易菜单跳转
  5. 搞定 C 语言指针进阶高频考点

二、先破局:一句话分清两个易混概念

  • 数组指针 :本质是指针,指向一个数组
  • 指针数组 :本质是数组,里面每个元素都是指针

口诀:后面两个字是什么,它就是什么。


三、数组指针(指向数组的指针)

1. 定义

cpp 复制代码
类型 (*指针名)[数组长度];

例如:指向 5 个 int 的数组

cpp 复制代码
int (*p)[5];
  • () 优先级很高
  • 先说明 p 是指针
  • 再说明它指向一个长度为 5 的 int 数组

2. 用途:指向二维数组

二维数组名,本质就是数组指针

cpp 复制代码
int arr[2][3] = { {1,2,3}, {4,5,6} };
int (*p)[3] = arr;

访问:

cpp 复制代码
// 第0行第1列
printf("%d", (*p)[1] );

完整示例

cpp 复制代码
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>

int main()
{
    int arr[2][3] = { {1,2,3}, {4,5,6} };
    int (*p)[3] = arr;

    printf("%d\n", (*p)[0]);     // 1
    printf("%d\n", (*(p+1))[0]); // 4

    return 0;
}

四、指针数组(存放指针的数组)

1. 定义

cpp 复制代码
类型 *数组名[长度];

例如:长度为 3 的指针数组

cpp 复制代码
int *arr[3];
  • [] 优先级比 *
  • 先说明 arr 是数组
  • 每个元素是 int* 类型指针

2. 最常用场景:多字符串管理

cpp 复制代码
char *strArr[] = {
    "Chinese",
    "Math",
    "English",
    "Programming"
};

完整示例

cpp 复制代码
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>

int main()
{
    char *courses[] = {
        "语文", "数学", "英语", "C语言"
    };

    for (int i = 0; i < 4; i++)
    {
        printf("%s\n", courses[i]);
    }

    return 0;
}

五、数组指针 vs 指针数组 对比表

写法 名字 本质 记忆
int (*p)[5] 数组指针 指针,指向数组 括号包住,是指针
int *p[5] 指针数组 数组,存指针 无括号,是数组

一句话区分:有括号是指针,没括号是数组。


六、函数指针(指向函数的指针)

1. 什么是函数指针?

函数在内存中也有地址。函数指针就是存放函数地址的指针。

2. 定义格式

cpp 复制代码
返回值类型 (*指针名)(参数列表);

示例:指向参数为 (int,int)、返回 int 的函数

cpp 复制代码
int (*fp)(int, int);

3. 最简单使用示例

cpp 复制代码
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>

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

int main()
{
    // 定义函数指针
    int (*fp)(int, int) = add;

    // 两种调用方式等价
    printf("%d\n", add(2, 3));
    printf("%d\n", fp(2, 3));

    return 0;
}

4. 实战用途:菜单跳转 / 回调函数

cpp 复制代码
void show() { printf("显示信息\n"); }
void add() { printf("添加数据\n"); }
void exitSys() { printf("退出系统\n"); }

int main()
{
    // 函数指针数组
    void (*funcArr[])(void) = { exitSys, show, add };

    int choice;
    scanf("%d", &choice);
    funcArr; // 直接调用对应函数
}

这是做菜单框架、状态机、插件化的基础。


七、高频易错点

  1. int (*p)[5] 写成 int *p[5],含义完全相反
  2. 函数指针少写括号 int *fp(int,int) 变成函数声明
  3. 数组指针越界,特别是二维数组使用时
  4. 函数指针类型不匹配(返回值 / 参数对不上)
  5. 函数指针赋值时加了 & 或漏写 &(其实都可以,但要规范)

八、本章核心总结

  1. 数组指针int (*p)[n] → 指针,指向数组
  2. 指针数组int *p[n] → 数组,存指针
  3. 口诀:括号是指针,无括号是数组
  4. 函数指针int (*fp)(int,int) 指向函数地址
  5. 函数指针可做回调、菜单跳转、简化分支逻辑
  6. 这一章是 C 语言进阶分水岭,搞懂才算真正入门指针

下期预告

下一篇学习 typedef,给复杂类型起别名,简化数组指针、函数指针等复杂写法,让代码更简洁易读。

相关推荐
飞鼠_2 小时前
详解c++中的sturct
开发语言·c++
小白学大数据2 小时前
分布式爬虫核心技术详解与工程实践
开发语言·分布式·爬虫·python
♛识尔如昼♛2 小时前
C 基础(8) - 函数
c语言·指针·递归·函数
CoderCodingNo2 小时前
【GESP】C++一级真题 luogu-B4495, [GESP202603 一级] 交朋友
开发语言·c++
海寻山2 小时前
Java内部类:4种类型+实战场景+面试避坑
java·开发语言·面试
梦游钓鱼3 小时前
stl常用容器说明
开发语言·c++
踏着七彩祥云的小丑3 小时前
Python——字符串常用操作
开发语言·python
成都易yisdong3 小时前
基于C#和WMM2025模型的地磁参数计算器实现
开发语言·c#