关于二级指针和二维数组两者差别很大,不可以直接用二级指针传递二维数组
首先来看看二维数组在内存中是如何组织的呢?
一维数组 T arr1 = new T[9]? 二维数组T arr2 = new T[3][3]

实际上,不管是一维还是多维数组,都是内存中一块线性连续空间,因此在内存级别上,其实都只是一维。但是不同的定义使得表现形式不一样,从而有多维数组的概念。访问数组元素其实非常简单,原因就在于元素在内存中的线性排列,这样对一维数组的访问只需要arr1[index] = *(arr1+index*sizeof(T));对二维数组的访问
arr2[i][j]=*(arr2+(i*col+j)*sizeof(T)),因此连续线性的数组访问效率很高。多维类似。
下面一个程序测试:
#include
/************************************************************************/
/* 数组和指针参数是如何被编译器修改的?
? “数组名被改写成一个指针参数”规则并不是递归定义的。数组的数组会被改写成“数组的指针”,而不是“指针的指针”:
?
? 实参? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 所匹配的形参
?
数组的数组? ? ? ? ? ? char c[8][10];? ? ? ? ? ? ? ? char (*c)[10];? ? ? ? 数组指针
?
指针数组? ? ? ? ? ? ? char *c[10];? ? ? ? ? ? ? ? ? char **c;? ? ? ? ? ? ? 指针的指针
?
数组指针(行指针)? ? ? char (*c)[10];? ? ? ? ? ? ? ? char (*c)[10];? ? ? ? 不改变
? ?
指针的指针? ? ? ? ? ? char **c;? ? ? ? ? ? ? ? ? ? ? char **c;? ? ? ? ? ? ? 不改变? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? */
/************************************************************************/
/*二级指针**作为形参,可以接受二级指针**p、指针数组*p[]作为实参的参数,从而传递二维数组*/
void print(int **p, int row, int col)
{
?int i=0,j=0;
?for(i=0;i
?{
? for(j=0;j
? {
? ?printf("%d\t",p[i][j]);
? }
?}
?printf("\n");
}
/*数组指针(*)[]作为形参,可以接受数组指针(*p)[3]作为实参的参数,从而传递二维数组*/
void print(int (*p)[3], int row, int col)
{
?int i=0,j=0;
?for(i=0;i
?{
? for(j=0;j<3;j++)
? {
? ?printf("%d\t",p[i][j]);
? }
?}
?printf("\n");
}
/*function 'void __cdecl print(int ** ,int,int)' already has a body Error executing cl.exe.
/*同二级指针*/
/*
void print(int *p[], int row, int col)
{
?int i=0,j=0;
?for(i=0;i
?{
? for(j=0;j
? {
? ?printf("%d\t",p[i][j]);
? }
?}
?printf("\n");
}
*/
/******以上两个函数无法重载overload,说明编译器把*p[]和**p? 都当成一种类型******************************************/
int main()
{
?int i = 0;
?int **pointer_to_pointer;
?//printf("%X\n",*pointer_to_pointer);//会错误,因为pointer_to_pointer 还未初始化,是野二级指针
?
?int *pointer = new int[9];
?
?int *pointer_array[3]; //指针数组,即是一个存放指针元素的数组,定义后即会有含有三个指针元素的数组,但是每个指针元素并没有初始化
?printf("%X\t%X\t%X\n",pointer_array,pointer_array+1,pointer_array+2);
?printf("%X\t%X\t%X\n",pointer_array[0],pointer_array[1],pointer_array[2]);
?
?int bi_array[3][3] = {{1,2,3},{4,5,6},{7,8,9}};
?int (*array_pointer)[3] = bi_array;//数组指针,指向数组的指针,可用于函数传递二维数组
?int single_array[3] = {1,2,3};
? ?//pointer_to_pointer = bi_array;? //!!! 错误,二级指针和二维数组首地址(实际内存空间不管是N维数组,都是一片连续的线性空间,二维数组元素访问a[i][j]是a+sizeof(type)*(C*i+j),因此a可以看成是一个指针而已)不是一个东西,二者不能相互赋值
? ? ? ? ? //cannot convert from 'int [3][3]' to 'int ** '
?//pointer_to_pointer = (int**)bi_array; // !!!慎用,因为虽然没有语法错误,但是会出现内存访问错误;
? ? //pointer_array = bi_array;//错误cannot convert from 'int [3][3]' to 'int *[3]'
?
?
?//pointer_to_pointer = bi_array+1;//错误cannot convert from 'int (*)[3]' to 'int ** '
?/*******************以上说明二维数组和二维指针不是等价的,不能相互赋值*************************************************/
?
?pointer_to_pointer = pointer_array;
?/*******以上这句说明指针数组*[]? 可以转换为二级指针** 他们相互等价*****************************************************/
?
?//pointer = bi_array;//错误cannot convert from 'int [3][3]' to 'int *'
?pointer = (int *)bi_array;
?for(i=0;i<9;i++)
?{
? printf("%d\t",pointer[i]);
?}
?printf("\n");
?
?
?//pointer = array_pointer;//错误cannot convert from 'int (*)[3]' to 'int *'
?pointer = (int *)array_pointer;
?for(i=0;i<9;i++)
?{
? printf("%d\t",pointer[i]);
?}
?printf("\n");
?for(i=0;i<9;i++){pointer[i] = 9;}? ? //此时指向bi_array的array_pointer的元素被pointer修改为9
?array_pointer = (int(*)[3])pointer;
?print(array_pointer,3,3);
?/********以上说明二维数组名和数组指针虽然是一个指针,但编译器并不理解,对他来说是数组类