指针数组和数组指针
指针数组:是指一个数组里面装着指针,也即指针数组是一个数组;
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**
在函数中操作元素
- *(a[i] + j) //代表第 i 行 第 j 列
- a[i][j] //同上
- *(*(a+i) + j) //同上
- *((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)