《C和C++代码精粹》——2.10 指针和多维数组

    xiaoxiao2024-04-07  138

    本节书摘来自异步社区出版社《C和C++代码精粹》一书中的第2章,第2.10节,作者: 【美】Chuck Allison,更多章节内容可以访问云栖社区“异步社区”公众号查看。

    2.10 指针和多维数组

    C和C++代码精粹实际上,在C++中没有多维数组!至少对多维数组没有直接的支持。人们通常把一个一维数组看作一个向量,把一个二维数组看作一个表或者矩阵,把一个三维数组看作一个长方体。然而,数组的几何模型使明智地使用高维数组变得很困难,取而代之的是C++支持“数组的数组”的概念。例如,如果一个一维的整型数组为

    int a[4]={0,1,2,3};

    它是一个有索引的整数集合:

    我们通常把它描述成一个向量:

    对一个二维整型数组,如:

    int a[3][4]={{0,1,2,3},{4,5,6,7},{8,9,0,1}}

    是像下面这样的向量集合:

    或者,如果喜欢的话可写成:

    这就是数组的集合。因此,a就是一个“3个具有4个整型元素的数组的数组”,a[0]就是这些具有4个整型元素的数组之一。由于在表达式中使用数组名时,它总是被解释为指向它的第一个元素的指针,所以一个诸如 a+1 之类的表达式就是“指向一个具有4个整型元素的数组的指针”,在这种情况下,该表达式将指向第二行(即a[1])。程序清单2.15中的程序说明了如何声明指向一个数组的指针,这样的指针可以在不改变下标语法的情况下,替换数组名。初学者容易错误地假设:指向整型数据的指针能代替一个整型数组名,就像以下程序:

    int a[]={0,1,2,3},*p=a; /*...*/ p[i]=...

    那么,这样指向整型数据的指针的指针将会对二维数组进行同样的操作,就像下面:

    int a[][4]={ {0,2,3,4},{4,5,6,7},{8,9,0,1}}; int **p=a; /*受怀疑的指针转换*/ /*...*/ p[i][j]=...

    要弄清以上做法为何不对,考虑一下表达式pi,根据“重要的指针原则2”,这就相当于:

    *(p[i]+j)

    也相当于:

    *(*(p+i)+j)

    程序清单2.15 说明在二维数组中指向一维数组的指针

    // array8.cpp: 使用一个一维数组指针 #include <iostream> main() { int a[][4] = {{0,1,2,3},{4,5,6,7},{8,9,0,1}}; int (*p)[4] = a; //指向包含4个整型成员的数组 size_t nrows = sizeof a / sizeof a[0]; size_t ncols = sizeof a[0] / sizeof a[0][0]; cout << "sizeof(*p) == " << sizeof *p << endl; for (int i = 0; i < nrows; ++i) { for (int j = 0; j < ncols; ++j) cout << p[i][j] << ' '; cout << endl; } } //输出: sizeof(*p) == 16 0 1 2 3 4 5 6 7 8 9 0 1

    由于p是一个指向整型数据的指针,所以表达式 p+i 往 p后面移动的距离等于i个指针的大小,而不是 i 行(我们需要移动 i 行)。显然,我们需要的指针类型是 p 所指向的指针具备一个行的大小,因此 p 必须是一个行指针,也就是说它指向一个大小合适的数组。因此,有趣但又有逻辑性的语法为:

    int (*p)[4]=a;

    根据p的这个定义,编译器依据下面的步骤来求表达式((p+i)+j)的值:

    1.p+i

    这一步计算行指针,该行超出行 p 当前所指向的 i 行。

    2.*(p+i)

    这是具体的行(是一个数组)。

    3.由于数组 *(p+i)不是 sizeof 或者 & 运算的操作数,所以它被指向它第一个元素的指针所替代,即 &ai ,这是一个指向整型(int)的指针。

    4.&ai+j

    因为&ai是一个指向整型(int)的指针,加上j就把这个指针向前移动了j个整型数据单位,结果是&ai。

    5.*&ai

    这就是整型a[i] [j]。

    表2.1总结了指针和二维数组的这种关系,注意,不要因为a+1和a[1]有同样的值(0×8)而得出以下的结论:

    a[i]==a+i // 错误!

    它们仅仅在数值上相等,而类型却不一样,因为sizeof(a+1)==2(一个指针),而 sizeof(a[1])= =8(一个有4个整型数的数组)。

    本文仅用于学习和交流目的,不代表异步社区观点。非商业转载请注明作译者、出处,并保留本文的原始链接。

    相关资源:敏捷开发V1.0.pptx
    最新回复(0)