简体   繁体   中英

Printing 2-D array through pointers

My teacher gave me a problem to solve in which: -

1) User will input "n" number of triangles.

2) After inputting "n", The user will input the sides of triangles.

3) We basically have to print those sides (Basically a question of 2-D arrays).

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?

If I put printf("%d ", *(*(array + i) + j)) then I get error:-

Indirection requires pointer operand ('int' invalid).

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

array + i has type int * , so *(array + i) has type int , which you can't dereference again.

Instead, you want to use i and j to get the correct index. The index you want is 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.

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] . 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) + 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.

Again, it's much prettier to use array notation, replacing *(*(array + i) + j)) with 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.

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]

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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