指向二维数组的指针

来源:互联网 发布:知乎 万历郑贵妃 编辑:程序博客网 时间:2024/05/22 23:59

int(*p)[10]定义了一个指向二维数组的指针p,赋给它10个长度。然后把a数组的值赋给(*p)[10],注意,这里是a数组是5行10列的,放入(*p)[10]是把a[0][0],a[0][1],a[0][2],a[0][3],a[0][4],a[0][5],a[0][6],a[0][7],a[0][8],a[0][9]放入(*p)[0]中,同理,将a[1][0...9]放入(*p)[1]。最后(*p)[10]中的值只有五行被初始化为a数组的值了。
在本例中,p和p[0]是同一个意思,就是数组a的起始地址,等价于cout<<a<<endl,但是他们有区别,p指向的是整个数组的首地址,而p[0]则指向a的首行首地址(继续往下看...)。
p[9]则值内存为p数组分配的(*p)[9]的地址。如果你仔细验证程序的输出结果,你就会发现:
#include<stdio.h>
#include "iostream"
using std::cout;
using std::endl;
using std::hex;
void main()
{
int a[5][10]={1,2};
int (*p)[10]=a;
cout<<p<<endl;
cout<<p[0]<<endl;
cout<<p[9]<<endl;
}
输出结果为(不同机器结果不同):
0012FEB8
0012FEB8
00130020
如果你验证它们这些地址存储的值,你会发现:
#include<stdio.h>
#include "iostream"
using std::cout;
using std::endl;
using std::hex;
void main()
{
int a[5][10]={1,2};
int (*p)[10]=a;
cout<<*p<<endl;
cout<<(*p)[0]<<endl;
cout<<(*p)[9]<<endl;
}
输出结果为:
0012FEB8
1
0
这是p和p[0]的区别就体现出来了。因为*p并不是取首元素的值,它这时才相当于p[0]。那如何通过p取得首元素的值呢,很显然,应该再加一个*操作符,如下:
cout<<**p<<endl;
这时输出结果自然就会和(*p)[0]一样是1了。


Fun (int **p){}这里面的int **p //这里的p不是二维数组的指针,而是指向指针的指针,即二级指针。

正确的二维数组的指针应该是:Int a[2][2];Int (*p)[2];//定义时无论数组维数,只可忽略第一维 

例如:int a[2][2]={0,1,2,3};

int **p=(int**)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),均引用了非法内存所以说,二位数组并不能简单的转换成指向指针的指针。  

二维数组其实只是一个指针,而二级指针是指向指针的指针,所以二者并不等价。如上例所示:int a[2][2];

 a是指向整个数组的首地址,并不是int **;所以不要指望向函数fun里面传实参 p=a;

 

感謝sld666666,我覺得那個應該是和下面的情況類似把,中間有個強制轉換的過程:

 

 

#include <iostream>

 

void fun(char ** p)

{

char (*p1)[10] = (char(*)[10])p;

std::cout<<p1[0][0]<<std::endl;

}

 

int main(int argc, char* argv[])

{

char data[][10] = {"abc","def"};

fun((char **)data);

return 0;

}

----------------------------------------------------------------华丽的分割线---------------------------------------------------------------------------------------------------------------------------

 

<c程序设计语言>中的关于这个的解释:

Newcomers to C are sometimes confused about the difference between a two-dimensional array and an array of pointers, such as name in the example above. Given the definitions 

   int a[10][20];

   int *b[10];

then a[3][4] and b[3][4] are both syntactically legal references to a single int. But a is a true two-dimensional array: 200 int-sized locations have been set aside, and the conventional rectangular subscript calculation 20 * row +col is used to find the element a[row,col]. For b, however, the definition only allocates 10 pointers and does not initialize them; initialization must be done explicitly, either statically or with code. Assuming that each element of b does point to a twenty-element array, then there will be 200 ints set aside, plus ten cells for the pointers. The important advantage of the pointer array is that the rows of the array may be of different lengths. That is, each element of b need not point to a twenty-element vector; some may point to two elements, some to fifty, and some to none at all. 

Although we have phrased this discussion in terms of integers, by far the most frequent use of arrays of pointers is to store character strings of diverse lengths, as in the function month_name. Compare the declaration and picture for an array of pointers: 

   char *name[] = { "Illegal month", "Jan", "Feb", "Mar" };

with those for a two-dimensional array: 

   char aname[][15] = { "Illegal month", "Jan", "Feb", "Mar" };

 

//我的理解是,当是指针数组的时候,可以直接传,如果是普通的二维数组的话应该就进行上面的转换。


0 0
原创粉丝点击