二级指针与二维数组

一个函数形如:

void f(float **p){

/* 想要在函数体中按二维数组的方式访问*/

    p[1][1] = 0;//c++用vc编译ok,运行出错(非法访问)

}

float **p; //其实这里的p并不是一个二位数组的指针,只不过是一个指向指针的指针

像你这样访问肯定是会出问题的。

例如:

float a[2][2]={0,1,2,3};

float **p=(float**)a;//强制将二维数组指针转为指向指针的指针

则此时

p[0]=0;

p[1]=1;

p[2]=2;

p[3]=3;

p[0][0]=*(*(p+0)+0)=**p;

p[0][1]=*(*(p+0)+1);

对于p[0][0]:由于*p=0; ====> **p=*(0);引用地址为零的内存,必然是错误的。

对于p[0][1]=*(*p+1)====>*(4),引用了非法内存

同样,对于p[1][0]=*(1),p[1][1]=*(5),均引用了非法内存

所以说,二位数组并不能简单的转换成指向指针的指针。

正确的指向二维数组的指针应该是:

float a[5][10];

float (*p)[10];//只需要定义为指向第二维的指针,忽略第一维

p=a;

p[0][1]=a[0][1];

 

二级指针和二维数组并不等价。

二级指针是一个指向指针的指针

而二维数组其实就是一个指针,char a[3][4]; a是指向整个二维数组的首地址。它相当于(char *)[n],并不是char **;

所以不能直接:t=a;

要这样:t = (char **)a;

我们知道char array[]=”abcdef”; array是数组的首地址,

那么在二维数组中array当然也是数组的首地址,

看看这个定义char Array[][3] ={“ab“,“cd“,“ef“};

怎么知道的呢?定义这样一个数组,在vc调试窗口中

我们看到:

Array ---------0x64324234

|------Array[0]---0x64324234 “ab“

|------Array[1]---0x64324337 “cd“

|------Array[2]---0x6432433A “ef”

已经很明白了,实际编译器是这样实现二维数组的,实际上Array是“一维指针数组“的首地址,其中每一个元素指针都对应一个字符串,那么好我们来看看是否可以这样来使用Array二维数组.

char **pArray = Array;编译器提示出错,怎么办呢?加个(char **)试试,仍然出错,设断看一下pArray的值和Array的值是相等的,但我们是否可以象使用Array那样来同样输出字符串呢?很明显是不行的,编译器不会把pArray+i处理成pArray+i*3寻找到第i个指针的地址,而只是简单的加了一个i.这说明编译器只做了很简单的将地址值赋给了pArray,而它实际没有任何意义.我们不能用它来访问任何数据.很奇怪吗?

再来看看这样定义char *p[] = {“ab“, “cd“, “ef“};定义了一个指针数组.char **sp = p;这样的用法经常看到,为什么这样就可以使用sp来访问字符串了呢,的确编译器在编译的时候识别出了sp是一个指向一维数组的指针的指针,那么我们就可以把它做为数组名来操纵整个数组了.

posted on 2015-11-18 19:41  acodewarrior  阅读(391)  评论(0编辑  收藏  举报

导航