Fork me on GitHub

C 与 C++ 中 指向二维数组的指针进行指针运算

二维数组在概念上是二维的,有行和列,但在内存中所有的数组元素都是连续排列的,它们之间没有“缝隙”。以下面的二维数组 nums 为例:

从概念上理解,nums 的分布像一个矩阵,但在内存中,a 的分布是一维线性的,整个数组占用一块连续的内存:

1     int nums[2][3] =  { 10,20,30,40,50,60 };
2     //以上定义与下边相同
3     int nums[2][3] = { {10,20,30}, {40,50,60} };

在几乎所有的程序语言中,二维数组都是按行排列的,先存放 nums[0] 行,再存放 nums[1] 行,最后存放 numsa[2] 行;

C 与 C++ 中 允许把一个二维数组分解成多个一维数组来处理。对于数组 nums,它可以分解成两个一维数组,即 nums[0]、nums[1],每一个一维数组又包含了 3 个元素,例如 nums[0] 包含 nums[0][0]、nums[0][1]、nums[0][2]

以下代码通过对指针进行移动,来查看指针运算后获得实际结果,你会发现数组指针加 * 取内容符前后打印内容一样,均为一个内存地址。这里要注意一点——数组名本身便是指针,但它不是指向数组的指针,是指向数组第一个元素的指针,指针前加*号后其实是取到了内容,但这个内容是这个数组元素的地址:

 1     int nums[2][3] =  { 10,20,30,40,50,60 };
 2 
 3     int(*p)[3] = nums;
 4 
 5     printf("p = %d\n",                   p                 );           // 指向第0行 第0个成员
 6     printf("*p = %d\n",                  *p                );           // 指向第0行 第0个成员,这里加 * 号,取的是数组指向元素的地址
 7     printf("*(*p) = %d\n",               *(*p)             );           // 访问第0行 第0个成员的值
 8     printf("p + 1 = %d\n",               p + 1             );           // 指向第1行 第0个成员
 9     printf("*(p + 1) = %d\n",            *(p + 1)          );           // 指向第1行 第0个成员,这里加 * 号,取的是数组指向元素的地址
10     printf("*(*(p + 1))= %d\n",          *(*(p + 1))       );           // 访问第1行 第0个成员的值
11     printf("*(p + 1) + 1 = %d\n",        *(p + 1) + 1      );           // 指向第1行 的第1个成员
12     printf("*(*(p + 1) + 1) = %d\n",     *(*(p + 1) + 1)   );           // 访问指向第1行的第1个成员的值

打印结果:

p = 2029920
*p = 2029920
*(*p) = 10
p + 1 = 2029932
*(p + 1) = 2029932
*(*(p + 1))= 40
*(p + 1) + 1 = 2029936
*(*(p + 1) + 1) = 50

 

posted @ 2020-11-14 01:14  索智源  阅读(349)  评论(0编辑  收藏  举报