《C和C++代码精粹》——2.11 更高深的内容-阿里云开发者社区

开发者社区> 开发与运维> 正文

《C和C++代码精粹》——2.11 更高深的内容

简介:

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

2.11 更高深的内容

C和C++代码精粹
我们可以很自然地得出以下结论:一个三维数组是二维数组的集合。

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

image

这个数组的第一个元素是一个“二维数组” a[0](从技术上来说,a[0]是一个由3个含有4个整数的数组的数组),为了使指针与数组名a一致,定义:

int (*p) [3] [4] = a;

程序清单2.16是一个应用该指针的程序示例,表2.2是与表2.1相似的三维数组。

表2.1 对于二维数组的数组指针转换

image

其中十六进制值是相对于a的地址偏移量。

程序清单2.16 说明在三维数组内指向二维数组的指针

// array9.c:    使用一个二维数组指针  
#include <iostream>  
using namespace std;  

main()  
{  
    int a[][3][4] = {{{0,1,2,3},{4,5,6,7},{8,9,0,1}},  
                     {{2,3,4,5},{6,7,8,9},{0,1,2,3}}};  
    int (*p)[3][4] = a;  
    size_t ntables = sizeof a / sizeof a[0];  
    size_t nrows   = sizeof a[0] / sizeof a[0][0];  
    size_t ncols   = sizeof a[0][0] / sizeof a[0][0][0];  

    cout << "sizeof(*p) == " << sizeof *p << endl;  
    cout << "sizeof(a[0][0]) == " << sizeof a[0][0] << endl;  
    for (int i = 0; i < ntables; ++i)  
    {  
        for (int j = 0; j < nrows; ++j)  
        {  
            for (int k = 0; k < ncols; ++k)  
                cout << p[i][j][k] << ' ';  
            cout << endl;  
        }  
        cout << endl;  
    }  
}  

//输出:  
sizeof(*p) == 48  
sizeof(a[0][0]) == 16  
0 1 2 3   
4 5 6 7   
8 9 0 1   

2 3 4 5   
6 7 8 9   
0 1 2 3

表2.2 关于三维数组的数组指针转换

表 达 式
image

其中,十六进制值是相对于a的地址偏移量。

在程序清单2.15和程序清单2.16中的程序表明如何确定一个数组和它所有的子数组的秩(即维数),对于程序清单2.15中的二维数组a,秩是它所包含的行数(一维对象),也就是:

sizeof  a /sizeof  a[0]

从名称上讲,每一个行的秩就是a中每一行的整数的个数(0维对象):

sizeof  a[0] /sizeof  a[0][0]

总的来说,如果a是一个n维数组,那么,a为n−1维对象

sizeof  a /sizeof  a[0]

的集合,a中每一个(n-1)维对象包含n-2维对象

sizeof  a[0] /sizeof  a[0][0]

每一个(n-2)维对象依次包含(n-3)维对象

sizeof  a[0][0] /sizeof  a[0][0][0]

等等,直到每一个一维对象中零维对象的个数为

sizeof  a[0][0]…[0] /sizeof  a[0][0]…[0][0]
    {_n_-_1__subscripts_}       {_n_-_1__subscripts_}

练习2.3

模仿表2.1和表2.2,完成下面四维数组的数组指针转换表:

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

image

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

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

分享:
开发与运维
使用钉钉扫一扫加入圈子
+ 订阅

集结各类场景实战经验,助你开发运维畅行无忧

其他文章