如果我有数组a
,我如何设置一个指针到第一行?
double a[2][4] = {{1, 2, 3, 4}, {5, 6, 7, 8}};
您可以声明一个指向一行的指针,并将其初始化为指向第一行:
double (*p_first_row)[4] = &a[0];
由于数组到指针的衰减,你也可以这样写:
double (*p_first_row)[4] = a;
括号是必要的,因为声明
double *p[4];
声明了一个指针数组,而
声明double (*p)[4];
声明指向数组的指针。
就像对任何指针那样对它进行正常的解引用。*(a + 0)
给出矩阵的第一行,*(a + i)
给出二维数组中的i-th
行。
获取2d数组每行第一个元素的示例代码如下所示:
double a[2][4] = {{1, 2, 3, 4}, {5, 6, 7, 8}};
for (int i = 0; i < 2; i ++) {
printf("%lf ", *(a + i)[0]);
}
输出:
1 5
如果你有一个多维数组,比如
T a[N1][N2][N3][N4];
,其中T
是某种类型说明符,N1
,N2
,N3
,N4
是某种正整数,那么要创建指向数组第一个元素的指针,只需将最左边的维度更改为星号,如
T ( *p )[N2][N3][N4] = a;
在此声明中,数组指示符a
隐式地转换为指向其第一个元素的指针。
如果您想获得指向数组(即类型为T[N2][N3][N4]
的数组)的第i个(0 <= i < N1
)元素的指针,您可以写入
T ( *p )[N2][N3][N4] = a + i;
或
T ( *p )[N2][N3][N4] = a;
p += i;
这是一个示范程序。
#include <stdio.h>
int main( void )
{
double a[2][4] =
{
{1, 2, 3, 4},
{5, 6, 7, 8}
};
for ( double ( *row )[4] = a; row != a + 2; ++row )
{
for ( double *p = *row; p != *row + 4; ++p )
{
printf( "%.1f ", *p );
}
putchar( 'n' );
}
}
程序输出为
1.0 2.0 3.0 4.0
5.0 6.0 7.0 8.0
- C语言中的2D数组是数组的数组
double a[2][4]
=一个大小为2的数组,每个项目的类型为double[4]
。 指向这样一个数组的指针被声明为- 任何C语言中的数组,无论何时在大多数表达式中使用,都会"衰减"。指向第一个元素的指针。
- 自
double [4]
double a[2][4]
第一项的类型,然后a
将衰变成一个指针指向这样一个项目,double (*)[4]
,每当一个表达式中使用。
double (*p)[2][4]
,初始化/赋值为p=&a
。同样,指向double a[4]
类型数组的指针被声明为double (*p)[4]
。因此,如果需要,可以像这样遍历double a[2][4]
:
double a[2][4] = {{1, 2, 3, 4}, {5, 6, 7, 8}};
for(double (*p)[4]=a; p<a+2; p++)
{
printf("%lf %lf %lf %lfn", (*p)[0],(*p)[1],(*p)[2],(*p)[3]);
}
也等价于double (*p)[4]=&a[0]
。
现在假设我们用更合理的语法编写一个表达式:
a[i][j]
根据定义,任何a[i]
表达式都100%等价于*(a+i)
。所以上面的代码相当于*(*(a+i)+j)
。
这里使用了两次指针算术:a+i
是double(*)[4]
类型的指针算术,增加i * sizeof(double[4])
字节的地址。而+j
部分是double*
上的指针算术,增加j * sizeof(double)
字节的地址。
因此a[1][0]
=(char*)a + 1 * sizeof(double[4]) + 0 * sizeof(double)
的例子:
#include <stdio.h>
int main()
{
double a[2][4] = {{1, 2, 3, 4}, {5, 6, 7, 8}};
printf("%lf ", a[1][0] );
printf("%lf ", (char*)a + 1 * sizeof(double[4]) + 0 * sizeof(double) );
}