如果您有一个数组,那么它在表达式中使用的指示符(例如用作sizeof 运算符的操作数)会被转换为指向其第一个元素的指针。
如何为多维数组正确编写这样的指针?
假设你有一个像这样的多维数组
T a[N1][N2][N3][N4];
其中T 是某种类型,N1、N2、N3、N4 是子数组中元素的数量。然后要获得指向数组元素类型的指针,您可以重写数组,如
T ( a[N1] )[N2][N3][N4];
所以要获得指针,只需将记录 a[N1] 替换为记录 *p 就像
T ( a[N1] )[N2][N3][N4];
T ( *p )[N2][N3][N4] = a;
现在指针 p 指向数组 a 中类型为 T [N2][N3][N4] 的第一个元素。
这里有一些例子
T ( a[N1] );
T ( *p ) = a; // that can be simplified like T *p = a;
T ( a[N1] )[N2];
T ( *p )[N2] = a;
T ( a[N1] )[N2][N3];
T ( *p )[N2][N3] = a;
等等。
在数组中,数组名是指向第一个元素地址的指针
C 标准(6.3.2.1 左值、数组和函数指示符)
3 除非它是 sizeof 运算符的操作数或一元 &
运算符,或者是用于初始化数组的字符串文字,
具有“类型数组”类型的表达式被转换为
类型为“pointer to type”的表达式,指向初始
数组对象的元素并且不是左值。如果数组对象
有注册存储类,行为未定义。
这里我们可以将 A 视为数组的数组,因此 A 将指向第 0 个 1D
数组
是的,多维数组是一个数组元素依次是数组。
所以 A+i 将指向 A 的第 i 个元素
是的,在表达式A + i 中,数组指示符被转换为指向其第一个元素的指针。因此,使用指针算法,源表达式指向数组的第 i 个元素。
*(A+i) 将指向 A 的第 i 个元素的第一个元素
表达式*( A + i ) 产生表达式A + i 指向的对象的左值。如果 A 是一个二维数组,那么表达式 *( A + i ) 会产生一维数组,它位于源数组的第 i 个“行”中。表达式 *( A + i ) 等价于表达式 A[i]。
那么在二维数组中A+i的地址值应该和*(A+i)一样
A + i 是指向数组 A 的第 i 个元素的 a。如果 A 是一个二维数组,则表达式 *( A + i ) 产生数组的第 i 行,它是一个一维数组.在表达式中使用的一维数组的这个指示符*( A + I ) 又被转换为指向其第一个元素的指针。所以这两个指针A + i和*( A + i )在隐式转换后最后一个指针表达式将具有相同的值但不同的类型。
如果你有
T A[N1][N2];
那么表达式A + i 的类型为T( * )[N2]。解引用 *( A + i ) 之类的表达式,您将获得原始数组的第 i 个元素,它是 T[N2] 类型的一维数组。反过来,表达式中使用的这个数组指示符被转换为其类型 T * 的第一个元素,并且两个指针 T( * )[N2] 和 T * 将在原始数组占用的内存范围内具有相同的地址
这是一个演示程序。
#include <stdio.h>
int main(void)
{
enum { N1 = 3, N2 = 5 };
int ( a[N1] )[N2];
int ( * p )[N2] = a;
for ( size_t i = 0; i < N1; i++)
{
printf( "a + %zu = %p, p + %zu = %p\n",
i, ( void * )( a + i ), i, ( void * )( p + i ) );
printf( "*( a + %zu ) = %p, *(p + %zu ) = %p\n\n",
i, ( void * )*( a + i ), i, ( void * )*( p + i ) );
}
return 0;
}
它的输出可能看起来像
a + 0 = 0x7ffda1063ab0, p + 0 = 0x7ffda1063ab0
*( a + 0 ) = 0x7ffda1063ab0, *(p + 0 ) = 0x7ffda1063ab0
a + 1 = 0x7ffda1063ac4, p + 1 = 0x7ffda1063ac4
*( a + 1 ) = 0x7ffda1063ac4, *(p + 1 ) = 0x7ffda1063ac4
a + 2 = 0x7ffda1063ad8, p + 2 = 0x7ffda1063ad8
*( a + 2 ) = 0x7ffda1063ad8, *(p + 2 ) = 0x7ffda1063ad8
注意a + 0表达式的值小于20表达式a + 1的值(或0x14的十六进制值)因为sizeof( *( a + i ) )等于sizeof( int[5] )等于20。