简体   繁体   English

通过指针打印二维数组

[英]Printing 2-D array through pointers

My teacher gave me a problem to solve in which: - 我的老师给我解决了一个问题,其中:-

1) User will input "n" number of triangles. 1)用户将输入“ n”个三角形。

2) After inputting "n", The user will input the sides of triangles. 2)输入“ n”后,用户将输入三角形的边。

3) We basically have to print those sides (Basically a question of 2-D arrays). 3)我们基本上必须打印这些面(基本上是二维数组的问题)。

This is my implementation of the problem: - 这是我对问题的执行:-

# 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;
}

The code works fine but I have a doubt in this line given below: - 代码工作正常,但我对下面给出的这一行表示怀疑:-

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");
}

Should it not be printf("%d ", *(*(array + i) + j)) instead of printf("%d ", (*(array + i) + j)) to get the values of the sides of triangle? 如果不是printf("%d ", *(*(array + i) + j))而不是printf("%d ", (*(array + i) + j))来获取边的值三角形?

If I put printf("%d ", *(*(array + i) + j)) then I get error:- 如果我把printf("%d ", *(*(array + i) + j))放进去printf("%d ", *(*(array + i) + j))我会报错:

Indirection requires pointer operand ('int' invalid). 间接需要指针操作数(“ int”无效)。

What I have learned in C is that in order to dereference a 2-D array pointer we have to use the former method instead of latter which I have used in my code. 我在C语言中学到的是,要取消对2-D数组指针的引用,我们必须使用前一种方法,而不是我在代码中使用的后一种方法。 Where am I going wrong? 我要去哪里错了?

You can't dereference twice. 您不能两次取消引用。 You're dealing with a 1D array, that you're using as a 2D one. 您正在处理一维数组,将其用作2D数组。

array + i has type int * , so *(array + i) has type int , which you can't dereference again. array + i类型为int * ,因此*(array + i)类型为int ,您不能再次取消引用。

Instead, you want to use i and j to get the correct index. 相反,您想使用ij获得正确的索引。 The index you want is i * 3 + j : 您想要的索引是i * 3 + j

*(array + i * 3 + j)

It's however much prettier to use the [] notation, which is equivalent: 但是,使用[]表示法更漂亮,它是等效的:

array[i * 3 + j]

*(*(array + i) + j)) could be used when you have a 2D array constructed by having an array of pointers to arrays, or when the type used is a multidimensional array. *(*(array + i) + j))可以在通过数组指针数组构造2D数组时使用,也可以在使用的类型为多维数组时使用。

For example: 例如:

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)));

(I've left out all checks for success of allocation. These must be included if this code was being used.) (我省去了所有检查分配成功的检查。如果正在使用此代码,则必须包括这些检查。)

Note that the last line of the example is very ugly. 请注意,示例的最后一行非常丑陋。 *(*(array + i) + j)) is equivalent to array[i][j] . *(*(array + i) + j))等价于array[i][j] It could therefore be rewritten: 因此可以将其重写:

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

Another use of the double-dereference is with multidimensional array types. 双引用的另一种用法是使用多维数组类型。

For example, if you know ahead of time the number of triangles: 例如,如果您提前知道三角形的数量:

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)));

In this case, we take advantage of the fact that array identifiers decay to pointers to their first element. 在这种情况下,我们利用了数组标识符衰减到指向其第一个元素的指针这一事实。 array + i is a pointer to the i th triangle, so *(array + i) is an lvalue of type int * pointing to the array 3 of int for the triangle i . array + i是第i个三角形的指针,因此*(array + i)int *类型的左值int *指向三角形iint数组3。

*(array + i) + j is an int * pointing to the side j of triangle i , so *(*(array + i) + j)) is an lvalue of type int for that element. *(array + i) + j是一个int *指向三角形i的边j ,因此*(*(array + i) + j))是该元素的int类型的左值。

Again, it's much prettier to use array notation, replacing *(*(array + i) + j)) with array[i][j] . 同样,使用数组表示法更漂亮,将*(*(array + i) + j))替换为array[i][j]

For starters you did not allocate a two-dimensional array. 对于初学者,您没有分配二维数组。 You allocated a one dimensional array with 3 * number_of_triangles elements. 您分配了带有3 * number_of_triangles元素的一维数组。

The program is invalid because in this loop 该程序无效,因为在此循环中

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.
    }
}

you are overwriting already inputted values. 您正在覆盖已经输入的值。

This expression 这个表达

((array + i) + j)

is equivalent to the expression 等效于表达式

array + ( i + j)

So array + ( 0 + 1 ) is equal to array + ( 1 + 0 ) That is if to use indices then the both expression are equivalent to &array[1] 所以array + ( 0 + 1 )等于array + ( 1 + 0 )就是说,如果使用索引,则两个表达式都等于&array[1]

if your compiler supports variable length arrays then the program can look like 如果您的编译器支持可变长度数组,则程序看起来像

#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;
}

You can the loops also rewrite like 您可以将循环也重写为

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' );
}

Otherwise you have to allocate a one dimensional array of pointers to one dimensional integer arrays. 否则,您必须将一维指针数组分配给一维整数数组。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM