二维数组转指针时可能会遇到的问题

来源:互联网 发布:fgo淘宝石头号注意事项 编辑:程序博客网 时间:2024/05/17 04:53

关于

<pre name="code" class="cpp">int t[2][2] = { 1,2,3,5 };int ** p = (int**)t;
</pre><p></p><pre>
这种写法,执行过后,会出现 

p[0]=1;

p[1]=2;

p[2]=3;

p[3]=5;

这种情况。也许有朋友会不理解。肯定很多初学者会认为 p[0][0]=1 而不是 p[0] =1;  其实不然,此时如果调用 p[0][0] 将会出错。因为 p[0]=0;然后 p[0][0] 相当于取 *(0) ,这当然是错误的。那为什么会出现上面的情况,其实 t 是一个二维数组,而 p 则是个二级指针(它们之间在某种程度上来说,差别很大,并不能同日而语,二维数组实质是一维数组,是一块连续的空间,而二维指针则不一定了),  p[0] ,p[1], p[2] ,p[3] 里面存放的都是一个指向一维指针的地址。查看 p 现在的内存可以看到:,而这正是 t 所指向的内存,他们指向同一块。

p[0]相当于 *(p+0); p[1] 相当于 *(p+1) ,由于 p 是二级指针,也就是它的变量(指针)占 4 字节 ,按 p 往后推算 4 字节就到了 p+1 指向的地址,此时正好是 2 。 

其实这里完全是因为巧合:int 类型占 4 字节,指针类型也是 4 字节。所以造成了一种假象:t 里面的每个数字被存放在了 p[n] (0<n<4) 里面。

其实看 p[0] 指向的内存可以看出来:,它是表示内存的 1 号单元。

如果我们换成 char (一个字节) 类型,就不会出现这种假象了,因为 char 只有一个字节,此时会将四个 char 同时存入一个 p[0] ,不会是分开存放了。

char t[2][2]= { '1', '2', '3', '5' };char ** p = (char**)t;
查看内存:,此时 p 和 t 都指向这里。

然而我们看 p[0] 则会发现 p[0]指向的地址是 

红圈里面的值正是 t 里面四个 char 的值,按照本机大小端方案排列,即 '1','2','3','5' 的 Ascii 码。此时 p[1] 呢? p[1]当然就是取 t 后面的 4 个未知的字节作为它的值了。。


0 0
原创粉丝点击