In
for ( p = arr; p <= arr+6; p++)
the expression arr
, as an rvalue, is a pointer to the first element of the array (which is of type int [3]
, so each time you increment that pointer, it moves three int
positions forward ---a whole row---, and so, arr + 6
points just after the sixth row of the array (if the array should ever had six rows) You can do it (with the proper explicit pointer conversions, as you are mixing pointers to int
with pointers to int [3]
) with the expression arr + 2
which is the addres of the first array element after the second row (and the number of rows of the array).
You can do it also declaring
int (*aux)[2][3] = &arr; /* aux is a pointer to the whole 3x2 array,
* so aux + 1 will be the position of the second
* 2D array after this one */
and then
int *end = (int *)(aux + 1);
or simply
int *end = (int *)(&arr + 1); /* see below */
(Beware that arr
and &arr
are both pointers and point to the same place, but they are not the same type (arr
is of type int (*)[3]
and &arr
is of type int(*)[2][3]
)
So let's rewrite your code as
for (p = (int *)arr; p < end; p++)
or
for (p = (int *)arr; p < (int *)&arr + 1; p++)
would work, which seems more natural to do the calculus in complete array units than in rows or single cells (and you can change freely the dimensions of the array)
Your code would be:
#include <stdio.h>
int main()
{
int arr[2][3] = { { 1, 2, 3 }, { 4, 5, 6 } };
int *end = (int *)(&arr + 1); /* try to avoid evaluating this expression in the loop
* despite that it can be optimized to comparing
* with a constant value */
char *sep = "";
for (int *p = (int *)arr; p < end; p++)
{
printf("%s%d", sep, *p);
sep = ", ";
}
putchar('\n');
return 0;
}
(Beware that you have to use <
operator and not <=
as you don't want to print the value pointed by end
, because it lies one place outside of the array)
Finally a note: this will work with true arrays, but not with function parameters declared as arrays, because they decay to pointers and then &arr
is not a pointer to data the size of the array, but it is the address of the parameter itself, which points to the array somewhere else.