C指针与一维二维数组、数组指针与指针数组、函数指针_数组的理解使用

文章目录

  • [一、指针数组 和 数组指针](#一、指针数组 和 数组指针)
    • [① 数组指针](#① 数组指针)
    • [② 指针数组](#② 指针数组)
  • 二、函数指针与函数指针数组
    • [① 函数指针](#① 函数指针)
    • [② 函数指针数组](#② 函数指针数组)
  • 三、指针与一维、二维数组
    • [① 指针与一维数组](#① 指针与一维数组)
    • [② 指针与二维数组](#② 指针与二维数组)

一、指针数组 和 数组指针

① 数组指针

数组指针(Array Pointer)是指向数组的指针变量 ,也可以理解为一维数组与指针的结合。其定义形式为

cpp 复制代码
type (*ptr)[size]; // 记法:数组指针本身是指针,所以需要括号将*与指针变量括起来

其中,type 表示数组元素的数据类型,ptr 是指向数组的指针变量,size 是数组的长度。

例如:

cpp 复制代码
arr[5] = { 1, 2, 3, 4, 5 };
int (*p)[5] = &arr;  // 定义一个指向长度为 5 的 int 类型数组的指针

上述代码中,p 是一个指向长度为 5 的 int类型数组的指针,指向 arr 数组的首地址。

通过数组指针可以访问数组中的元素。

例如:

cpp 复制代码
(*p)[0] = 10;  // 修改 arr 数组的第一个元素为 10

需要注意的是,在使用数组指针访问数组元素时,需要使用 (*p)[i] 的形式。

<><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><>


② 指针数组

指针数组(pointer array) 是一个数组,其元素都是指针变量 。其定义形式为

cpp 复制代码
type *ptr[size]; // 指针数组本身是数组,每个元素是指针变量,故不加括号([] 优先级高于 *)

其中,type 表示指针变量所指向的数据类型,ptr 是指针数组,size 是数组的长度。

例如:

cpp 复制代码
int a = 1, b = 2, c = 3;
int *ptr[3] = { &a, &b, &c };  // 定义一个包含三个 int 类型指针变量的数组

上述代码中,ptr 是一个包含三个 int 类型指针变量的数组,分别指向 a、b、c 三个变量。

通过指针数组可以访问指向的变量。 例如:

cpp 复制代码
*ptr[0] = 10;  // 修改 a 变量的值为 10

需要注意的是,在使用指针数组访问指针变量所指向的数据时,需要使用 *ptr[i] 的形式。


综上所述,数组指针和指针数组是两个不同的概念,使用时需要根据实际情况选择合适的方式。

<><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><>


二、函数指针与函数指针数组

① 函数指针

函数指针(Function Pointer) 是指向函数的指针变量。它可以用来存储和调用函数的地址,实现对函数的动态调用。函数指针的类型必须与所指向的函数的类型一致,包括返回值类型和参数列表。

声明函数指针的格式如下:

cpp 复制代码
return_type (*pointer_name)(params);

其中,return_type函数的返回值类型pointer_name函数指针的名称params函数的参数列表


以下是一个简单的示例,展示了如何声明、赋值和调用函数指针

cpp 复制代码
#include <iostream>

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

int main() {
    int (*ptr)(int, int) = add;  // 声明一个函数指针 ptr,并将其赋值为函数 add 的地址
    ptr();  // 调用函数指针 ptr,相当于调用函数add
    
    return 0;
}

在上述代码中,声明了一个函数指针 ptr,它指向无返回值且无参数的函数 add。然后将函数 add 的地址赋值给 ptr,最后通过 ptr() 调用了函数 add

函数指针在许多情况下非常有用,例如在 回调函数、函数指针数组、函数指针作为函数参数 等场景中都能发挥重要作用。通过函数指针,可以实现函数的灵活调用与动态选择。


② 函数指针数组

函数指针数组(Array of Function Pointers)是一个包含函数指针元素的数组。每个数组元素都是一个函数指针,它们可以指向不同的函数。通过函数指针数组,可以实现对不同函数的动态调用和选择。

声明函数指针数组的格式如下:

cpp 复制代码
return_type (*array_name[size])(params);

以下是一个简单的示例,展示了如何声明、赋值和调用函数指针数组:

cpp 复制代码
#include <iostream>

int mul(int a, int b) {
    return a * b;
}

int div(int a, int b) {
    return a / b;
}

int main() {
    int (*ptrArr[2])() = {mul, div};  // 声明一个包含 2 个函数指针元素的函数指针数组,并将其赋值为函数 mul 和函数 div 的地址

    for (int i = 0; i < 2; i++) {
        ptrArr[i]();  // 调用函数指针数组中的函数指针
    }
    
    return 0;
}

在上述代码中,声明了一个函数指针数组 ptrArr,它包含了两个函数指针元素。第一个元素指向函数 mul,第二个元素指向函数div通过遍历函数指针数组,逐个调用函数指针,实现了对函数的动态调用。

如果我们要使用switch语句来进行堆函数的调用,可以替换为函数指针数组。

函数指针数组在一些场景中非常有用,例如函数回调、状态机等。通过函数指针数组,可以根据需要灵活地选择和调用不同的函数,使程序具有更高的可扩展性和灵活性。


三、指针与一维、二维数组

① 指针与一维数组

指针与一维数组在 C/C++ 中有紧密的关联,并可以相互转换

  1. 数组名作为指针

在 C/C++ 中,数组名可以被看作是指向数组首元素的指针。

例如:

cpp 复制代码
int arr[5] = { 1, 2, 3, 4, 5 };
int *ptr = arr;  // 数组名 arr 被隐式地转换为指向数组首元素的指针

上述代码中,ptr 是一个指向整型变量的指针,它被赋值为数组 arr 的首地址。此时,可以通过指针 ptr 访问数组中的元素,例如 ptr[0] 表示数组 arr 的第一个元素。

需要注意的是,虽然数组名可以被看作指针,但它并不是一个普通的指针变量,无法进行赋值操作或修改其值。

  1. 指针数组和一维数组的转换

指针数组和一维数组可以相互转换。 例如:

  • 将指针数组转换为一维数组:
cpp 复制代码
int a = 1, b = 2, c = 3;
int *ptr[3] = { &a, &b, &c };  // 定义一个指针数组
int arr[3] = { *ptr[0], *ptr[1], *ptr[2] };  // 将指针数组转换为一维数组

上述代码中,通过 解引用指针数组的元素,可以获取指针所指向的值,然后将这些值赋给一维数组。

  • 将一维数组转换为指针数组:
cpp 复制代码
int arr[3] = { 1, 2, 3 };
int *ptr[3];

for (int i = 0; i < 3; i++) {
    ptr[i] = &arr[i];
}

上述代码中,通过循环遍历一维数组,可以将数组中每个元素的地址存储到指针数组中,从而实现一维数组到指针数组的转换。


总结:指针与一维数组之间存在紧密的关系,并可以相互转换。通过理解和灵活运用指针与一维数组的特性,可以更自由地操作和处理数组数据。


② 指针与二维数组

指针与二维数组在 C/C++ 中也有一定的关联,并可以相互转换

  1. 指针与二维数组的关系

对于二维数组,可以使用指针来进行访问和操作。我们知道,二维数组实际上是由多个一维数组组成的,每个一维数组都是连续存储的。

cpp 复制代码
int arr[][3] = { {1, 2, 3}, {4, 5, 6} };
int (*ptr)[3] = arr;  // 使用指针指向二维数组的首地址

上述代码中,ptr 是一个指向包含3个整数的一维数组的指针。它被赋值为二维数组 arr 的首地址。

通过指针 ptr 可以访问二维数组中的元素,例如 ptr[i][j] 表示二维数组 arr 中第 i 行、第 j 列的元素值。

需要注意的是,在使用指针访问二维数组时,需要使用 (*ptr)[j] 的形式。


  1. 指针与二维数组的转换

指针与二维数组也可以相互转换。

例如:

  • 将指针转换为二维数组:

可以通过将指针转换为二维数组来进行操作和访问。

cpp 复制代码
int (*ptr)[3] = new int[2][3];  // 动态分配一个二维数组
int arr[2][3] = *ptr;  // 将指针转换为二维数组

上述代码中,通过使用 new 运算符动态分配一个二维数组,并将其赋给指针 ptr。然后,通过解引用指针,将指针转换为二维数组。

  • 将二维数组转换为指针:

可以通过将二维数组转换为指针来实现某些操作和传递给函数。

cpp 复制代码
int arr[2][3] = { {1, 2, 3}, {4, 5, 6} };
int (*ptr)[3] = arr;  // 将二维数组转换为指针

上述代码中,将二维数组 arr 赋给指针 ptr,这样就将二维数组转换为指针


总结:指针与二维数组之间有一定的关联,并可以相互转换。通过理解和灵活运用指针与二维数组的特性,可以更自由地操作和处理二维数组数据。

相关推荐
JingHongB7 分钟前
代码随想录算法训练营Day55 | 图论理论基础、深度优先搜索理论基础、卡玛网 98.所有可达路径、797. 所有可能的路径、广度优先搜索理论基础
算法·深度优先·图论
weixin_4327022610 分钟前
代码随想录算法训练营第五十五天|图论理论基础
数据结构·python·算法·深度优先·图论
小冉在学习13 分钟前
day52 图论章节刷题Part04(110.字符串接龙、105.有向图的完全可达性、106.岛屿的周长 )
算法·深度优先·图论
Repeat71513 分钟前
图论基础--孤岛系列
算法·深度优先·广度优先·图论基础
小冉在学习16 分钟前
day53 图论章节刷题Part05(并查集理论基础、寻找存在的路径)
java·算法·图论
武子康28 分钟前
大数据-212 数据挖掘 机器学习理论 - 无监督学习算法 KMeans 基本原理 簇内误差平方和
大数据·人工智能·学习·算法·机器学习·数据挖掘
passer__jw7671 小时前
【LeetCode】【算法】283. 移动零
数据结构·算法·leetcode
Ocean☾1 小时前
前端基础-html-注册界面
前端·算法·html
顶呱呱程序1 小时前
2-143 基于matlab-GUI的脉冲响应不变法实现音频滤波功能
算法·matlab·音视频·matlab-gui·音频滤波·脉冲响应不变法
TeYiToKu1 小时前
笔记整理—linux驱动开发部分(9)framebuffer驱动框架
linux·c语言·arm开发·驱动开发·笔记·嵌入式硬件·arm