指针数组与数组指针---傻傻分不清楚?
创始人
2024-05-11 10:57:15
0

目录

  • 1.指针数组
  • 2.数组指针

1.指针数组

什么是指针数组呢?
我们通过以前学过的数组进行类比:

  • 整形数组是存放整形的数组
  • 字符数组是存放字符的数组
  • 所以,指针数组是存放指针(地址)的数组

整形数组的书写形式是int arr[10],字符指针书写形式是char arr[10],所以字符指针的书写形式是int *arr[10] char* arr[10]
接下来创建一个字符指针数组

int main()
{char a = 'a';char b = 'b';char c = 'c';char d = 'd';char* arr[4] = {&a,&b,&c,&d};return 0;
}

创建了四个char类型变量,将他们取地址放到字符指针数组里,这是最基本的应用

还可以将字符串放到字符指针数组里,字符串本质上是数组,数组名是数组首元素地址,所以将四个字符串名放到字符指针数组里即可

int main()
{char str1[] = "hello";char str2[] = "world";char str3[] = "byebye";char str4[] = "world";char* arr[4] = {str1,str2,str3,str4};return 0;
}

在这里插入图片描述

还可以用一维指针数组模拟二维数组

#include 
int main()
{int arr1[5] = { 1,2,3,4,5 };int arr2[5] = { 2,3,4,5,6 };int arr3[5] = { 3,4,5,6,7 };int arr4[5] = { 5,6,7,8,9 };int arr5[5] = { 0,1,0,2,0 };int* arr[5] = { arr1,arr2,arr3,arr4 ,arr5};for (int i = 0; i < 5; i++){for (int j = 0; j < 5; j++){printf("%d ", *(*(arr + i) + j));}printf("\n");}return 0;
}

前面说过,对于一个指针p , *(p+i)p[i]等价
所以上述程序中的*(*(arr + i) + j)也可以写成arr[i][j],也就是如二维数组一样的写法
这个指针数组的结构:
在这里插入图片描述


2.数组指针

对于数组指针,还是类比其他类型指针

  • 整形指针是一个指向整形变量的指针
  • 字符变量是一个指向字符变量的指针
  • 所以数组变量就是一个指向数组的指针
  • 整形指针的类型是int*,字符指针的类型是char*,所以数组指针的类型就是int(*)[10]
char ch = 'w';
char *pc = &ch;int num = 10;
int* pi = #int arr[10];
int(*pa)[10] = &arr;

在这个整形数组指针,*先与pa结合:(*pa),所以int(*pa)[10]是一个指针

在这里赋给数组指针的是数组名取地址,那么数组名和数组名取地址有什么区别呢?请点击跳转另一篇文章:数组与地址,数组名到底是什么?


数组指针到底怎么用呢?

之前如果要输出一个整形数组,我们可以使用指针,这里的指针通常是数组元素首地址

但是如果非要用数组指针输出数组中的元素也是可以的

int main()
{int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };int(*p)[10] = &arr;for (int i = 0; i < 10; i++){printf("%d ", (*p)[i]);}return 0;
}

这里的p是一个数组指针,先将解引用*p,得到数组,然后通过下标访问(*p)[i])就可以得到数组元素了

但是这样做是很别扭的,不如直接用整形指针输出

其实 数组指针在一位数组中用的不多,在二维数组中会用到

在以往的对于二维数组的传参,定义函数时,在参数列表中最简单的写法是直接以二维数组的形式传形参

void print(int arr[3][4], int x, int y) //直接以二维数组的形式写是最简单的
{for (int i = 0; i < x; i++){for (int j = 0; j < y; j++){printf("%d ", arr[i][j]);}printf("\n");}
}
int main()
{int arr[3][4] = { {1,2,3,4},{2,3,4,5},{3,4,5,6} };print(arr, 3, 4);
}

但是,对于一位数组int arr[10],如果在函数中想要接受它,不但可以以数组的形式接受,用一个一级指针接受也是可以的


void printf(int arr[10],int x,int y)  //可以用数组的形式接收
{;
}void printf(int *arr,int x,int y) //也可以用指针的形式接收
{;
}
int main()
{int arr[10] = { {1,2,3,4},{2,3,4,5},{3,4,5,6} };print(arr, 3, 4);
}

如果也想要用一个指针去接受二维指针就略有不同了

函数实参传一个二维数组名过去,数组名是数组首元素地址,所以二维数组数组名就是一个一维数组的地址,这个二维数组名其实就是一个数组指针,所以在函数中要用一个数组指针去接收

void print(int(*arr)[4],int x,int y)  //用一个数组指针去接收
{for (int i = 0; i < x; i++){for (int j = 0; j < y;j++){printf("%d ", (*(arr+i))[j]);}printf("\n");}
}
int main()
{int arr[3][4] = { {1,2,3,4},{2,3,4,5},{3,4,5,6} };print(arr, 3, 4);
}

学过了数组指针和指针数组,看看下面这些都是什么?

int arr[5];
int *parr1[10];
int (*parr2)[10];
int (*parr3[10])[5];
  1. int arr[5],是一个长度为5的整形数组
  2. int *parr1[10],是一个整形指针数组,长度为10,里面存放整形指针
  3. int (*parr2)[10],是一个数组指针,parr2指向一个长度为10的整形指针
  4. int (*parr3[10])[5],这个比较复杂,一步一步分析,首先看名称parr3先与[10]结合,所以这是一个数组,长度为10,然后剩下int(*)[5],所以在数组parr3中存放的是类型为int(*)[5]的数组指针,它指向一个长度为5的整形数组。

相关内容

热门资讯

监控摄像头接入GB28181平... 流程简介将监控摄像头的视频在网站和APP中直播,要解决的几个问题是:1&...
Windows10添加群晖磁盘... 在使用群晖NAS时,我们需要通过本地映射的方式把NAS映射成本地的一块磁盘使用。 通过...
protocol buffer... 目录 目录 什么是protocol buffer 1.protobuf 1.1安装  1.2使用...
在Word、WPS中插入AxM... 引言 我最近需要写一些文章,在排版时发现AxMath插入的公式竟然会导致行间距异常&#...
【PdgCntEditor】解... 一、问题背景 大部分的图书对应的PDF,目录中的页码并非PDF中直接索引的页码...
Fluent中创建监测点 1 概述某些仿真问题,需要创建监测点,用于获取空间定点的数据࿰...
educoder数据结构与算法...                                                   ...
MySQL下载和安装(Wind... 前言:刚换了一台电脑,里面所有东西都需要重新配置,习惯了所...
修复 爱普生 EPSON L4... L4151 L4153 L4156 L4158 L4163 L4165 L4166 L4168 L4...
MFC文件操作  MFC提供了一个文件操作的基类CFile,这个类提供了一个没有缓存的二进制格式的磁盘...