打印

请教一个C指针问题,关于二维数组

[复制链接]
1882|3
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
le062|  楼主 | 2010-9-25 22:32 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
沙发
HWM| | 2010-9-26 08:35 | 只看该作者
re LZ:

在此,a是一个指向int [4]类型的指针。故a+1的指针增量是sizeof(int [4]),即*p内容是5。

使用特权

评论回复
板凳
HWM| | 2010-9-26 08:57 | 只看该作者
关于C中的多维数组:


关于数组,我曾经发过相应的内容,翻了一下,再表如下:


数组实际上是一个由分层次叠加构造而成的一种数据结构,其最底层的基础就是下标操作符。作为一种操作符不仅可以和数组联用,还可以通过重载改变其原始语义(具体可见新手版内 C++ 随笔-21)。

只要有了一个常量指针,配合下标操作符的使用,就可以形成一个数组的雏形(前提是具备一个以常量指针为起始点的存储空间)。当然作为数组的雏形自然有其缺陷,那就是缺少数组的长度信息,以至于不可能得到其有效的整体特性。因此作为一个“完整”的数组定义还必须加入数组的长度信息。但作为一维数组,相关定义并未改变其“数组名”和下标操作符的基本属性。

那么多维数组情形又将是如何的呢?显然由于多维数组必须含有n-1维下标长度的信息(n>1),所以不可能存在上述数组的原始实现(仅用起始指针和下标)。那么多维数组具体又是如何定义的呢?先列出定义形式:

type A[N1][N2]...[Nn];

其中n为数组的维数,N1...Nn为数组各维的长度。

类似的,若将A独立拿出来看,它还是一个指向数组起始位置的常量指针。问题是在此情况下所指对象的“类型”是什么?是否还能象一维数组那样所指类型为数组单元变量类型呢?显然不行,因为这样的话将失去多维数组中相当重要的长度信息。那么不指向数组单元变量又指向什么呢?答案是,A将被定义为指向“数组类型”type [N2]...[Nn]的指针。由此,实际上还可以得出这样一个结论,数组A是被组织成N1个类型为type [N2]...[Nn]的单元的“一维数组”,其中*(A+i)为此“一维数组”的第i+1个单元(即i+1个数组的数组名)。以此类推,可以得到这样一个表达式:

    *(...*(*(A+i)+j)+...k) <=> A[j]...[k]

利用这种层次叠加构造法,顺理成章地建立了从最原始的数组雏形,通过不断地增加维长信息,最终到多维数组空间的形成机制。

下面列出一个具体的实例:

#include "stdafx.h"

int A[10][20][30];
int x, y;

int main(int argc, char* argv[])
{
    A[1][2][3] = 1234;
    *(*(*(A+3)+2)+1) = 4321;
    x = *(*(*(A+1)+2)+3);
    y = A[3][2][1];

    return 0;
}

附:数组的定义

数组是由一个指向首单元的常量指针(数组名)所引领的一组一定数量的连续单元所组成的数据结构。此常量指针的尺寸大小(尺寸的拓广)定义为整个数组的大小。此常量指针的地址(地址的拓广)定义为数组首单元的地址。多维数组type A[N1][N2]...[Nn]定义为一个常量指针(数组名)为A,由N1个单元(类型为type [N2]...[Nn],数组名为*(A+i)的数组,i=0...N1-1)组成的一维数组。这里的单元要理解成相关数组的常量指针(数组名)。


由以上数组的定义可以对实例中的相关表达式作以下分析:

    *(*(*(A+1)+2)+3)

先看A,它是一个指向数组首单元(类型为int [20][30])的常量指针(此单元为*A)。那么*(A+1)就是指向第二个单元(第二个类型为int [20][30]的数组的常量指针)。然后在此数组(常量指针或数组名为*(A+1))内再得到类型为int [30]的第三个数组的常量指针*(*(A+1)+2)。最后在这个数组(常量指针或数组名为*(*(A+1)+2))中指定类型为int的第四个单元*(*(*(A+1)+2)+3),即数组A的单元变量A[1][2][3]。

用地址算式可以表示如下

        *((int*)A + (1*sizeof(*(A)) + 2*sizeof(*(*(A))) + 3*sizeof(*(*(*(A)))))/sizeof(int))

其中
    *(A+1)            的地址为    (int*)A +  1*sizeof(*(A))/sizeof(int)
    *(*(A+1)+2)       的地址为    (int*)A + (1*sizeof(*(A)) + 2*sizeof(*(*(A))))/sizeof(int)
    *(*(*(A+1)+2)+3)  的地址为    (int*)A + (1*sizeof(*(A)) + 2*sizeof(*(*(A))) + 3*sizeof(*(*(*(A)))))/sizeof(int)

使用特权

评论回复
地板
le062|  楼主 | 2010-9-26 21:18 | 只看该作者
十分感谢,   *(...*(*(A+i)+j)+...k) <=> A[j]...[k]
很好很强大

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

13

主题

435

帖子

4

粉丝