在C语言中使用指针表达式迭代2D数组

6
我正在练习指针,并希望用指针操作代替数组遍历数组元素。我已经阅读了许多文章,但无法理解这个概念。有人能解释一下吗?
在这里,我制作了一个二维数组,并使用基本的嵌套for循环对其进行了迭代,但想使用指针。
int test[3][2] = {1,4,2,5,2,8};

for (int i = 0 ; i < 3; i++) {

    for (int j = 0; j < 2; j++) {

        printf("%d\n", test[i][j]);
    }
}

分步骤进行。编写一些代码来迭代遍历一个一维数组并使其正常工作。将其复制到一个函数中,并使其在一个一维数组上正确工作。这样就快完成了。迭代一个维度并在每个元素(即每个一维数组)上调用该函数。 - Martin James
1
printf("%d\n", ((test+i) + j)); 打印f("%d\n", ((test+i) + j)); - ryan
5个回答

10
int test[3][2] = {{1,4},{2,5},{2,8}};

// Define a pointer to walk the rows of the 2D array.
int (*p1)[2] = test;

// Define a pointer to walk the columns of each row of the 2D array.
int *p2 = NULL;

// There are three rows in the 2D array.
// p1 has been initialized to point to the first row of the 2D array.
// Make sure the iteration stops after the third row of the 2D array.
for (; p1 != test+3; ++p1) {

    // Iterate over each column of the arrays.
    // p2 is initialized to *p1, which points to the first column.
    // Iteration must stop after two columns. Hence, the breaking
    // condition of the loop is when p2 == *p1+2
    for (p2 = *p1; p2 != *p1+2; ++p2 ) {
        printf("%d\n", *p2);
    }
}

2
一些解释会更好地说明你的答案。不过完全基于指针的方法也值得一赞... :-) - alk

2
尝试以下内容并进行调查。
#include <stdio.h>

int main(void) 
{
    int test[3][2] = { { 1,4 }, { 2,5 }, { 2,8 } };

    for ( int ( *p )[2] = test ; p != test + 3; ++p ) 
    {
        for ( int *q = *p; q != *p + 2; ++q ) printf( "%d ", *q );
        puts( "" );
    }

    return 0;
}   

输出结果为

1 4 
2 5 
2 8

第一个指针是指向类型为int [2]的对象的指针,它指向数组的第一行,然后由于增量而指向其他行。第二个指针是指向类型为int的对象的指针。它指向内部循环中每行的第一个元素。

2
在一些编译器中,您还可以使用单个循环,将多维数组视为按行主序读取的一维数组进行读取。
这在金(King)的《C程序设计:现代方法》(第2版,第268页)中有提到。
#include <stdio.h>

int main(void)
{
    int test[3][2] = {{1,4},{2,5},{2,8}}, *p;

    for(p = &test[0][0]; p <= &test[2][1]; p++)
    {
        printf("%d\n", *p);
    }
    return 0;
}

1

使用指针算术来迭代,将二维数组视为一维数组非常容易。

void print_2d_array(int *num, size) {
    int counter = 0;
    while (counter++ < size) {
        printf("%i ", *num);
        num++;
    }
    printf("\n");
}

int main() {
    int matrix[2][3] = {{2, 11, 33},
                       {9, 8,  77}};

    int matrix_size = sizeof(matrix) / sizeof(int); // 24 bytes / 4 (int size) = 6 itens 

    print_2d_array(matrix, matrix_size);

    return 0;
}

0
如果“指针声明”是你练习的目标,可以使用以下初始化方式:
int (*pTest)[rmax][cmax] = test;

一旦你这样做了,使用指针索引的语法就与数组索引的语法相似,只是你必须使用*解引用运算符。

for (int i= 0; i < 3; i++) { 
  for (int j= 0; j < 2; j++) {
     printf ("%d ", *(pTest[i][j])); 
  }
  printf ("\n"); 
}

然而,如果您的目标是进行指针算术练习,则以下方法也可以:

int *res = &test;
for (int i = 0; i < 3; i++) {
  for (int j = 0; j < 2; j++) {
    printf ("%d ", *(res + i*2 + j)); 
  }
  printf ("\n"); 
}

输出

1 4  
2 5  
2 8

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接