二维指针、二维数组、指向数组的指针 函数参数传递「建议收藏」

二维指针、二维数组、指向数组的指针 函数参数传递「建议收藏」intarr[3][3]的本质是指向数组的指针即int (*p)[3],所以二维数组名可以传递给foo(int(*arr)[3]),或者foo(int[][3]),但是不能传递给foo(int**arr) 传给函数foo(int**arr)可以是动态二维数组

大家好,欢迎来到IT知识分享网。

int arr[3][3] 的本质是指向数组的指针即 int  (*p)[3],所以二维数组名可以传递给foo( int (*arr)[3]) ,或者foo(int [][3]),但是不能传递给foo(int **arr) ;传给函数foo(int **arr) 可以是动态二维数组,但是若是把二维数组名显式强转为二维指针,尽管可能没有编译错误,但结果却并不是想要的(详情见后文引用文章)。动态二维数组是这样定义的:

int **arr = new int* [3]

for ..

arr[i] = new int[3] ; //注意等式左边

那么要想传递二维数组最好用foo(int *arr,int M,int N),将矩阵维度显示传进去,函数里面不能用[][]操作符了,而是用指针运算的办法*(arr+N*i+j)得到元素值,这样可以避免一维数组指针使用固定列宽;另外,如果仍想使用[][]操作符,可以使用stl容器的办法,如vector<vector<int> > vec这样。

下面文章转自博客园http://www.cnblogs.com/wanpengcoder/archive/2010/07/17/1779503.html

二维数组和二级指针

 前两天写个程序,传参数的时候想传个二维数组进去,结果悲剧了,函数写成

Fun (int **p){},原来没有这么写过,以为这么写也是对的,结果错了,查了些资料,
做个总结。
 
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;

前两天写个程序,传参数的时候想传个二维数组进去,结果悲剧了,函数写成Fun (int **p){},原来没有这么写过,

以为这么写也是对的,结果错了,查了些资料,做个总结。

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” };

 

二维指针、二维数组、指向数组的指针 函数参数传递「建议收藏」

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

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/24338.html

(0)

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注

关注微信