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

一、指针数组 和 数组指针

① 数组指针

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

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

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

例如:

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

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

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

例如:

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

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

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


② 指针数组

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

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

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

例如:

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

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

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

*ptr[0] = 10;  // 修改 a 变量的值为 10

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


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

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


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

① 函数指针

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

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

return_type (*pointer_name)(params);

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


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

#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)是一个包含函数指针元素的数组。每个数组元素都是一个函数指针,它们可以指向不同的函数。通过函数指针数组,可以实现对不同函数的动态调用和选择。

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

return_type (*array_name[size])(params);

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

#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++ 中,数组名可以被看作是指向数组首元素的指针。

例如:

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

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

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

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

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

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

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

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

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

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


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


② 指针与二维数组

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

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

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

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. 指针与二维数组的转换

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

例如:

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

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

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

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

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

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

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

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


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

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值