Given the following code (derived rather closely from what you show in the question) in a file xx.c:
#include <stdio.h>
int main(void)
{
enum { M = 4, N = 5 };
int a[N][M];
for(int (*p)[M] = &a[0][0]; p <= &a[N-1][M-1]; p++)
{
scanf("%d", p);
}
return 0;
}
The GCC 4.8.2 compiler (running on an Ubuntu 12.04 derivative) says:
$ gcc -g -O3 -std=c99 -Wall -Wextra -Werror -c xx.c
xx.c: In function ‘main’:
xx.c:8:21: error: initialization from incompatible pointer type [-Werror]
for(int (*p)[M] = &a[0][0]; p <= &a[N-1][M-1]; p++)
^
xx.c:8:33: error: comparison of distinct pointer types lacks a cast [-Werror]
for(int (*p)[M] = &a[0][0]; p <= &a[N-1][M-1]; p++)
^
xx.c:10:5: error: format ‘%d’ expects argument of type ‘int *’, but argument 2 has type ‘int (*)[4]’ [-Werror=format=]
scanf("%d", p);
^
cc1: all warnings being treated as errors
$
The first error is because p is a pointer to an array of size M, but &a[0][0] is just a pointer to an int. The comparison failure is similar. You could write:
for (int (*p)[M] = &a[0]; p < &a[N]; p++)
That then leaves the scanf() error to be resolved. The trouble there is that you're passing a pointer to an array to a function that expects a pointer to an int. Further, because of the way array pointer increments work, you are attempting to read one number for the whole of one row of data. If you proceed down this path, you'd need a nested loop:
for (int *q = &(*p)[0]; q < &(*p)[M]; q++)
if (scanf("%d", q) != 1)
...process data format error...
On the other hand, you can simplify your life by using:
for (int *p = &a[0][0]; p < &a[N][M]; p++)
if (scanf("%d", p) != 1)
...process data format error...
This is the route I'd recommend you take if you are required to use pointers (to int). Pointers to arrays are to be avoided as much as possible, which is almost all of the time.
The two variants are here encapsulated into one program, along with code using array indices (suggested by Jim Balter in a comment), which is much the simplest and hardest to get wrong:
#include <stdio.h>
extern void error(const char *msg);
int main(void)
{
enum { M = 4, N = 5 };
int a[N][M];
// Pointers to arrays - nasty
for (int (*p)[M] = &a[0]; p < &a[N]; p++)
{
for (int *q = &(*p)[0]; q < &(*p)[M]; q++)
{
if (scanf("%d", q) != 1)
error("Bother");
}
}
// Pointers to int - OK
for (int *p = &a[0][0]; p < &a[N][M]; p++)
{
if (scanf("%d", p) != 1)
error("Bother");
}
// Array indices - can't go wrong easily!
for (int n = 0; n < N; n++)
{
for (int m = 0; m < M; m++)
{
if (scanf("%d", &a[n][m]) != 1)
error("Bother");
}
}
return 0;
}
scanf()is one of the trickier functions to use correctly; it is subtle and endlessly devious. Did you come up with the code in the question on your own? Using a pointer to an array is a non-trivial exercise, and I think your code should be compiling with some warnings about mismatched types (in theforline and in thescanf()line).