二维数组和二级指针(转)

摘要:
本文转载自“二维数组和二级指针”。感谢您的分享。两天前,我编写了一个程序,试图在传递参数时将二维数组传递到其中。结果是悲惨的。函数被编写为func{}。我以前没写过。我认为这也是正确的。结果是错误的。我检查了一些数据并做了总结。对于p[0][1]=*==˃*,还引用了非法内存。对于p[1][0]=*,p[1][1]=*,引用了非法内存。因此,二进制数组不能简单地转换为指向指针的指针。二维数组实际上只是一个指针,而二级指针是指向指针的指针,因此两者并不等价。

本文转载来自《二维数组和二级指针》,感谢分享。

前两天写个程序,传参数的时候想传个二维数组进去,结果悲剧了,函数写成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; //这里也是碰巧了, 指针和int都是4字节,恰巧每次移动到了对应值得位置;如果换成别的类型,或者64位设备就不会这么巧了;

而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" };

二维数组和二级指针(转)第1张

with those for a two-dimensional array: 

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

二维数组和二级指针(转)第2张

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

免责声明:文章转载自《二维数组和二级指针(转)》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇OSError: libcudart.so.7.5: cannot open shared object file: No such file or directoryC/C++中无条件花括号的妙用下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Inside the C++ Object Model 深度探索对象模型 5Construction 6Runtime 7Object

5构造,解构,拷贝语意学 Semantics of Construction, Destruction, Copy 纯虚拟函数的存在 Presence of Pure VF >pure virtual function可以被定义和调用invoke: 只能被静态调用statically, 不能经由虚拟机调用; Ex. inline void Abstr...

c++的深拷贝和浅拷贝

1.在使用一个对象对另一个对象初始化或赋值时,若对象包含指针成员变量,则需要手动的编写拷贝构造函数实现深拷贝,调用编译器的内部默认的拷贝构造函数则只能实现浅拷贝操作。通过蓝色操作:在拷贝指针的同时为指针重新分配内存空间。 2.通过深拷贝(显示重载=操作符,或显示定义拷贝构造函数)解决浅拷贝出现的问题...

matlab学习(2)——SVD()diag()函数

奇异值分解 (sigular value decomposition,SVD) 是另一种正交矩阵分解法;SVD是最可靠的分解法,但是它比QR 分解法要花上近十倍的计算时间。[U,S,V]=svd(A),其中U和V代表二个相互正交矩阵,而S代表一对角矩阵。 和QR分解法相同者, 原矩阵A不必为正方矩阵。 使用SVD分解法的用途是解最小平方误差法和数据压缩...

Redis 数据结构的实现

Redis 数据结构的实现 先看个对照关系: Redis数据结构 实现一 实现二 string 整数(如果value能够表示为整数) 字符串 hash 压缩列表(只包含少量键值对, 并且每个键值对的键和值要么就是小整数值, 要么就是长度比较短的字符串) 字典 list 压缩列表(只包含少量列表项, 并且每个列表项要...

套接字地址结构

大多数套接字函数都需要一个指向套接字地址结构的指针作为参数。每个协议簇抵都定义它自己的套接字地址结构 这些结构的名字均以sockaddr_开头,并以对应每个协议簇的唯一后缀结尾 1.IPv4套接字地址结构 IPv4套接字地址结构通常称为:网际套接字地址结构 它以sockaddr_in命名 struct in_addr{ in_addr_t  s_addr;...

C++ 有关指针作为函数参数的问题,自定义内存分配函数传递二级指针的问题

如题所示,我们主要讨论在自定义的内存分配函数中通常见到的代码如下所示: void Create(A** addr); 其中传递的参数是二级指针。为什么? 我们先看一下完整的动态内存分配函数的简单例子: struct A { int a = 0; int b = 0; int c[3]; }; void Create(A** addr) {...

最新文章