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.