通过指针打印二维数组

时间:2019-08-26 16:08:31

标签: c

我的老师给我解决了一个问题,其中:-

  

1)用户将输入“ n”个三角形。

     

2)输入“ n”后,用户将输入三角形的边。

     

3)我们基本上必须打印这些面(基本上是二维问题   数组)。

这是我对问题的实现:-

# include <stdio.h>
# include <stdlib.h>
# include <stdbool.h>
int main(void)
{
    int number_of_triangles; // Takes the value of number of triangles the user will input.
    scanf("%d", &number_of_triangles);

    int *array;
    array = malloc(number_of_triangles * 3 * sizeof(int)); 
//trying to create a 2D array whose column size is fixed i.e. 3.


    int i,j; // Counter variables.

    for(i = 0; i < number_of_triangles; i++)
    {
        for(j = 0; j < 3; j++)
        {
            scanf("%d", ((array + i) + j)); // Scanning value of sides of triangle.
        }
    }

    for(i = 0; i < number_of_triangles; i++)
    {
        for(j = 0; j < 3; j++)
        {
            printf("%d ", (*(array + i) + j));//printing those sides. <-This is the problem statement.
        }
        printf("\n");
    }
    return 0;
}

代码工作正常,但我对下面给出的这一行表示怀疑:-

for(i = 0; i < number_of_triangles; i++)
{
    for(j = 0; j < 3; j++)
    {
        printf("%d ", (*(array + i) + j));
//printing those sides. <-This is the problem statement.
    }
    printf("\n");
}

获取三角形边的值不是printf("%d ", *(*(array + i) + j))而不是printf("%d ", (*(array + i) + j))

如果我输入printf("%d ", *(*(array + i) + j)),则会收到错误消息:-

  

间接需要指针操作数('int'无效)。

我在C语言中学到的是,为了取消引用二维数组指针,我们必须使用前一种方法,而不是我在代码中使用的后一种方法。我要去哪里错了?

2 个答案:

答案 0 :(得分:1)

您不能两次取消引用。您正在处理一维数组,用作二维数组。

array + i的类型为int *,因此*(array + i)的类型为int,您不能再次取消引用。

相反,您想使用ij来获取正确的索引。您想要的索引是i * 3 + j

*(array + i * 3 + j)

然而,使用[]表示法相当漂亮:

array[i * 3 + j]

*(*(array + i) + j))可以用于具有通过指向数组的指针的数组构成的2D数组,或者使用的类型是多维数组时。

例如:

int **array;
array = malloc(number_of_triangles * sizeof(int *)); 

for (int i = 0; i < number_of_triangles; ++i)
    array[i] = malloc(3 * sizeof(int));

for (int i = 0; i < number_of_triangles; ++i)
    for (int j = 0; j < 3; ++j)
        printf("array[%d][%d]: %d\n", i, j, *(*(array + i) + j)));

(我省去了分配成功的所有检查。如果正在使用此代码,则必须包括这些检查。)

请注意,示例的最后一行非常难看。 *(*(array + i) + j))等同于array[i][j]。因此可以将其重写:

        printf("array[%d][%d]: %d\n", i, j, array[i][j]);

双重引用的另一种用法是使用多维数组类型。

例如,如果您提前知道三角形的数量:

int array[5][3];

for (int i = 0; i < 5; ++i)
    for (int j = 0; j < 3; ++j)
        printf("array[%d][%d]: %d\n", i, j, *(*(array + i) + j)));

在这种情况下,我们利用了数组标识符衰减到指向其第一个元素的指针这一事实。 array + i是第i个三角形的指针,因此*(array + i)是类型int *的左值,指向三角形{{的int的数组3 1}}。

i是指向三角形*(array + i) + j的边int *的{​​{1}},因此ji类型的左值元素。

同样,使用数组表示法更漂亮,将*(*(array + i) + j))替换为int

答案 1 :(得分:0)

对于初学者,您没有分配二维数组。您为一维数组分配了3 * number_of_triangles个元素。

该程序无效,因为在此循环中

for(i = 0; i < number_of_triangles; i++)
{
    for(j = 0; j < 3; j++)
    {
        scanf("%d", ((array + i) + j)); // Scanning value of sides of triangle.
    }
}

您正在覆盖已经输入的值。

此表达式

((array + i) + j)

等同于表达式

array + ( i + j)

因此array + ( 0 + 1 )等于array + ( 1 + 0 ),即如果使用索引,则两个表达式都等于&array[1]

如果您的编译器支持可变长度数组,则程序看起来像

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    int number_of_triangles; // Takes the value of number of triangles the user will input.
    scanf("%d", &number_of_triangles);

    int ( *array )[3] = malloc( sizeof( int[number_of_triangles][3] ) );

    for ( int ( *p )[3] = array; p != array + number_of_triangles; ++p )
    {
        for( int *q = *p; q != *p + 3; ++q )
        {
            scanf( "%d",  q ); // Scanning value of sides of triangle.
        }
    }


    for ( int ( *p )[3] = array; p != array + number_of_triangles; ++p )
    {
        for( int *q = *p; q != *p + 3; ++q )
        {
            printf( "%d ", *q );
        }
        putchar( '\n' );
    }

    free( array );

    return 0;
}

您还可以像这样重写循环

for ( int i = 0; i < number_of_triangles; i++ )
{
    for( int j = 0; j < 3; j++ )
    {
        scanf( "%d",  *( array + i ) + j ); // Scanning value of sides of triangle.
    }
}


for ( int i = 0; i < number_of_triangles; i++ )
{
    for( int j = 0; j < 3; j++ )
    {
        printf( "%d ", *( *( array + i ) + j ) );
    }
    putchar( '\n' );
}

否则,您必须将一维指针数组分配给一维整数数组。

相关问题