【C++の相关概念】指针数组 数组指针 二维数组传参

参考
数组过于简单,但你该了解这些!

指针数组和数组指针

指针数组:是指一个数组里面装着指针,也即指针数组是一个数组;

int *a[10];
在这里插入图片描述

数组指针:是指一个指向数组的指针,它其实还是一个指针,只不过是指向数组而已;

int(*a)[10]; //a指向一个列数为10的二维数组

区分方法:主要看后面的两个字是什么(前面是修饰作用),因此指针数组是数组,而数组指针是指针。

二维数组传参

形参为二维数组

内存排布
在这里插入图片描述

在这里插入图片描述

声明

void function(int a[m][n]);//函数声明
void function(int (&a)[m][n]);//二维数组的引用声明
void function(int a[][n]);//不论多少维数组,第一维(代表行宽)都可省略。
//虽然第一种函数声明定义了行数,但是实际传递的实参长度可以大于m
//例void function(int a[5][10]);可以传入实参int a[10][10];
//但此时function函数只取a的前5行,而后5行不取


void function(int a[][]);
//但是不能直接省略一二维参数,
//因为从实参传递来的是数组的起始地址,
//在内存中按数组排列规则存放(按行存放),而并不区分行和列,
//如果在形参中不说明列数,则系统无法决定应为多少行多少列

调用

function(a);//函数调用  实参直接写数组名!数组名!(重点)。
//(注意)function(a[m][n])或function(a[][n])都不可以!

在函数操控元素

1.   *(a[i] + j)  //代表第 i 行 第 j 列
2. 	a[i][j]	//同上
3.  *(*(a+i) + j) //同上
4. *((int *)a +i*n +j )//同上
	//n表示第二维数组长度,即列宽,
	//注意这里(int*)a是不可缺少的

形参为数组指针

(其实只是 声明定义 与第一种不同,其他一样)
声明

void function(int (*a)[n]);
//不是(int *a[n])(指针数组) ,而是(int (*a)[n])(数组指针);
// 缘由是 [] 的 优先级比 *的大

调用

function(&a);//函数调用  实参同样直接写数组名!
//(注意)function(a[m][n])或function(a[][n])同样都不可以!
//(注意)例:
//int A[10], B[8];
//void func(int (*p)[10]);
//func(&A); 合法
//func((int (*)[10])B); 合法,若不强转则不合法

在函数操控元素

1.   *(a[i] + j)  //代表第 i 行 第 j 列
2. 	a[i][j]	//同上
3.  *(*(a+i) + j) //同上
4. *((int *)a +i*n +j )//同上
	//n表示第二维数组长度,即列宽,
	//注意这里(int*)a是不可缺少的

形参为二级指针

声明

void function(int **a,int n);n表示第二维数组长度,即列宽

调用

function( (int **)a,int n);//实参不能为数组名!*与上面相反*!有两个 * !

//(注意)function(a)或function((int *)a)不可以!

在函数操控元素

 *((int *)a +i*n +j )
	//n表示第二维数组长度,即列宽,
	//注意这里(int*)a是不可缺少的

也可以使用int(*)[n]强转a的类型,然后再执行如下的操作:
1.   *(a[i] + j)  //代表第 i 行 第 j 列
2. 	a[i][j]	//同上
3.  *(*(a+i) + j) //同上

总结

声明定义(分三种)。
二维数组,数组指针,二级指针。(都是指针)

调用
数组指针,二维数组对应的类型为数组指针 Type(*)[n]
二级指针 Type**

在函数中操作元素

  1. *(a[i] + j) //代表第 i 行 第 j 列
  2. a[i][j] //同上
  3. *(*(a+i) + j) //同上
  4. *((int *)a +i*n +j )//同上
    //n表示第二维数组长度,即列宽,
    //注意这里(int*)a是不可缺少的

注意
a可以用静态数组和动态数组声明

void fun(int array[][D]); //case 1
void fun(int*array)[D]); //case 2
void fun(int ** array); //case 3

int main(){
	int a[N][D];//静态数组声明
	int** A;
	A = new int*[N];//Type* A=new Type[N]; 注意:N代表行数,即先确定函数再去顶列数
	for(int i=0;i<N;i++)
		A[i] = new int[D];	//动态数组声明

	fun(a);	//适用于case 1和case 2,因为这两种情况参数都为数组指针
	fun((int**) a); //适用于case 3,因为参数为二维指针,故须强转

	fun((int(*)[D]) A);	//适用于case 1和case 2,因为这两种情况参数都为数组指针
	fun(A); //适用于case 3
	
}

注意
在这里插入图片描述
需要区分好p和q的区别,其中p是数组指针,q是一维指针,虽然他们指向的位置相同,但是用法不同,即p[1][2]等效于*(q+1*3+2)等效于*(*(a+1)+2)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值