I am trying to print a 2-D array in C by using pointers but I am not getting the expected output.
Program:-
#include <stdio.h>
int main()
{
int arr[2][3] = {{1,2,3},{4,5,6}};
int* p;
for ( p = arr; p <= arr 6; p )
{
printf("%d ", *p);
}
return 0;
}
Output:-
1 2 3 4 5 6 -1116112128 1587637938 0 0 1893963109 32521 -1453950296 32766 -1453805568 1 800797033 21984 -1453949463
Could you tell me where I am wrong as the output should only be:
1 2 3 4 5 6
CodePudding user response:
Could you tell me where I am wrong
The elements of arr
are not integers, but arrays of 3 integers. So arr 6
is surely a different address than what you expect, since pointer arithmetic works in multiples of the size of the type in the array.
You'll always be better off using nested loops to iterate over a multidimensional array; treating it as one single-dimensional array of int
leads to exactly the kinds of confusion you see here. The code is harder to understand and verify, it won't be any slower.
CodePudding user response:
First, when looping through arrays of size n
wth an index i
, the condition for continuation should be i < n
rather than i <= n
, because array indexes in C run from 0
through n-1
.
However, your code has a more serious error: 1-dimensional arrays can be 'decayed' into pointers to the elements' type; however, 2-dimensional arrays decay into pointers to 1-dimensional arrays. So, in your case, the type of the pointer used in the arr 6
expression is a pointer to an array of three integers; further, when the 6
is added, that operation is performed in terms of the size of the pointed-to object, which is sizeof(int) * 3
– so, even when changing the <=
to <
, you will be running far beyond the actual bounds of the array.
To make the pointer arithmetic work in the correct 'units' (i.e. sizeof(int)
), cast the arr
to an int*
before the addition (and also change the <=
to <
):
#include <stdio.h>
int main()
{
int arr[2][3] = { {1,2,3},{4,5,6} };
int* p;
for (p = (int*)arr; p < (int*)arr 6; p ) {
printf("%d ", *p);
}
return 0;
}
CodePudding user response:
You are trying to access the value in the wrong way, The two-dimensional array is saved as a continuous block in the memory. So, if we increment the value of ptr by 1 we will move to the next block in the allocated memory.
int arr[2][3] = {{1,2,3},{4,5,6}};
int *ptr = arr;
int i,j;
for (i = 0; i < 6; i ) {
printf("%d ", *(ptr i));
}
return 0;
CodePudding user response:
Array designators used in expressions with rare exceptions are implicitly converted to pointers to their first elements.
The type of the array elements of this array
int arr[2][3];
is int [3]
. So a pointer to the first element of the array has the type int ( * )[3]
.
This assignment
p = arr;
where p
has the type int *
is incorrect because the operands of the assignment have incompatible pointer types.
At least you need to cast the right expression to the type int *
like
p = ( int * )arr;
The same casting you need to use in the condition in the for loop. That is instead of
p <= arr 6
you have to write
p < ( int * )arr 6
Below there is a demonstration program that shows how to output a two-dimensional array as a two-dimensional array using pointers.
#include <stdio.h>
int main( void )
{
int arr[2][3] = {{1,2,3},{4,5,6}};
for ( int ( *p )[3] = arr; p != arr 2; p )
{
for ( int *q = *p; q != *p 3; q )
{
printf( "%d ", *q );
}
putchar( '\n' );
}
return 0;
}
If you want to output the two-dimensional array as a one-dimensional array then you can write
#include <stdio.h>
int main( void )
{
int arr[2][3] = {{1,2,3},{4,5,6}};
for ( int *p = ( int * )arr; p != ( int * )arr 6; p )
{
printf( "%d ", *p );
}
putchar( '\n' );
return 0;
}