关于
<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 个未知的字节作为它的值了。。