使用一个指针指向某一行在c



如果我有数组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]
  • 指向这样一个数组的指针被声明为double (*p)[2][4],初始化/赋值为p=&a。同样,指向double a[4]类型数组的指针被声明为double (*p)[4]
  • 任何C语言中的数组,无论何时在大多数表达式中使用,都会"衰减"。指向第一个元素的指针。
  • double [4]double a[2][4]第一项的类型,然后a将衰变成一个指针指向这样一个项目,double (*)[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+idouble(*)[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) );
}

相关内容

  • 没有找到相关文章

最新更新