Reputation: 184
I'm a beginner and am trying to understand how multidimensional arrays work
Please look at this code:
#include<stdio.h>
void getData(int c;int *a,int r,int c)
{
for(int i=0;i<r;i++)
for(int j=0;j<c;j++)
scanf("%d",(*(a+i)+j)); //warning
return;
}
void putData(int c;int *a,int r,int c)
{
for(int i=0;i<r;i++)
for(int j=0;j<c;j++)
printf("%d",*(*(a+i)+j)); //error
printf("\n");
}
int main(void)
{
int r1,r2,c1,c2;
printf("Enter order of A:\n");
scanf("%d %d",&r1,&c1);
printf("Enter order of B:\n");
scanf("%d %d",&r2,&c2);
int a[r1][c1],b[r2][c2];
getData((int *)a,r1,c1);
getData((int *)b,r2,c2);
putData((int *)b,r2,c2);
}
I'm having trouble with understanding how the pointers are passed to the functions and the cause for the errors. But I think if i can understand how the pointers work then I might be able to debug it. Please help! Thanks!
Edit: I really want to understand how the pointer works with the addressed and stuff. So if there is some sort of tracing, it might help me
Upvotes: 0
Views: 55
Reputation: 84561
When you pass a VLA as a parameter (or any 2D array for that matter), you must at minimum pass the number of elements per-row so you can declare a complete type for your VLA (2D array).
While you can pass:
void getData (int r, int c, int a[r][c])
You can also pass:
void getData (int r, int c, int (*a)[c])
(as the first level of indirection is converted to a pointer, see: C11 Standard - 6.3.2.1 Other Operands - Lvalues, arrays, and function designators(p3) -- and note the exceptions)
c
must be included in the parameter list before a
or the type for a
will be incomplete as c
is not yet defined.
While you can write *(*(a + i) + j)
as equivalent pointer notation for a[i][j]
-- don't, it is less readable (but totally equivalent).
Always, ALWAYS, always validate EVERY input. Otherwise you risk invoking Undefined Behavior following in input or matching failure with scanf
, e.g.
printf("Enter order of A:\n");
if (scanf ("%d %d", &r1, &c1) != 2) { /* validate EVERY input */
fputs ("error: invalid input (r1, c1).\n", stderr);
return 1;
}
Putting it altogether, you could do:
#include <stdio.h>
#include <stdlib.h> /* for EXIT_FAILURE */
void getData (int r, int c, int (*a)[c])
{
for (int i = 0; i < r; i++)
for (int j = 0; j < c; j++)
if (scanf ("%d", &a[i][j]) != 1) {
fputs ("error: invalid input a[i][j].\n", stderr);
exit (EXIT_FAILURE);
}
}
void putData (int r, int c, int (*a)[c])
{
for (int i = 0; i < r; i++) {
for(int j = 0; j < c; j++)
printf (" %2d", a[i][j]); /* more readable */
/* printf (" %2d", *(*(a + i) + j)); */
putchar ('\n'); /* use putchar for a single char, instead of printf */
}
}
int main(void)
{
int r1, r2, c1, c2;
printf ("Enter order of A:\n");
if (scanf ("%d %d", &r1, &c1) != 2) { /* validate EVERY input */
fputs ("error: invalid input (r1, c1).\n", stderr);
return 1;
}
printf ("Enter order of B:\n");
if (scanf ("%d %d", &r2, &c2) != 2) { /* validate EVERY input */
fputs ("error: invalid input (r2, c2).\n", stderr);
return 1;
}
int a[r1][c1], b[r2][c2];
getData (r1, c1, a);
getData (r2, c2, b);
puts ("a");
putData (r1, c1, a);
puts ("\nb");
putData (r2, c2, b);
}
(note: the inclusion of stdlib.h
for the EXIT_FAILURE
macro, and note the additional spacing in the code -- helps older eyes)
Example Use/Output
$ echo "2 3 2 3 1 2 3 4 5 6 7 8 9 10 11 12" | ./bin/scanfvla
Enter order of A:
Enter order of B:
a
1 2 3
4 5 6
b
7 8 9
10 11 12
Look things over and let me know if you have further questions.
Upvotes: 3