1D数组衰减到指针,但2D数组​​不这样做,为什么?

Ton*_*ion 8 c c++ pointers

有人可以向我解释为什么技术上2D阵列实际上并没有衰减,int**而当你有一个单维数组时,你会得到指针衰减int*(如果你有数组int).

我理解指针衰减是什么,但我不明白为什么2D数组不会出现这种衰变?

对于C或C++新手而言,这是一个常见的混淆,但我发现自己也常常绊倒它.

Mar*_*ins 6

它们具有不同的内存布局.2D数组是一个连续的内存块,int**而是一个指针数组.对于2D数组,将位置偏移量计算为rownum * collength + colnum(反之亦然,具体取决于标记行/列的方式).这是行不通的int**,实际上会产生两个内存读取; 第一个获取列指针,然后读取与该内存偏移的数据.

顺便提一下,这种不同的布局是必须在接受2D数组的函数中声明数组维度(除了最左边)之外的原因; 否则,编译器无法生成计算偏移量的代码.

以下是对内存布局图片的尝试int**.左列是一个连续的指针数组,每个指针都包含一个连续的内存块和数据的地址.请注意,每列中的数据长度不必相同(尽管对于代码可读性而言可能不一定是好事):

int **array; 
int i, j;
int cntr = 1;
array = malloc( 3 * sizeof( int* ));
for ( i = 0; i < 3; i++ ) {
   array[i] = malloc( 4 * sizeof( int ));
   for ( j = 0; j < 4; j++ )
      array[i][j] = cntr++;
   }
Run Code Online (Sandbox Code Playgroud)

给出这样的东西:

array ==> |addr1|  ==>  [1,2,3,4]
          |addr2|  ==>  [5,6,7,8]
          |addr3|  ==>  [9,10,11,12]
Run Code Online (Sandbox Code Playgroud)

相比之下,这就是布局的样子int[3][4].括号只显示每列数据的逻辑中断.整数值在内存中是连续的:

int array[3][4];
int i, j;
int cntr = 1;
for ( i = 0; i < 3; i++ )
   for ( j = 0; j < 4; j++ )
      array[i][j] = cntr++;
Run Code Online (Sandbox Code Playgroud)

给出这样的东西:

array ==> [1,2,3,4][5,6,7,8][9,10,11,12]
Run Code Online (Sandbox Code Playgroud)