0

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

10
  • 1
    When indexing a 1D array the function knows how to index the array based on the type of the data. For example when you use an integer, let’s say one integer takes up 4 bytes (machine dependent) when you pass array, you pass a pointer to the first element in the array, the function can then find arr[1] by incrementing the pointer by the size of an integer, for example 4 bytes. Think of what extra info the function might need if it is a 2D array and you try to access arr[0][1] Commented Apr 12, 2019 at 1:26
  • so should it be *(*(a*i)+j) ? Commented Apr 12, 2019 at 1:29
  • unfortunately I don’t have time right now. Hopefully someone will help, if not I’ll come back tomorrow. I would look up something like “how a 2D array is passed to a function”. Commented Apr 12, 2019 at 1:37
  • Possible duplicate of How to pass 2D array (matrix) in a function in C? Commented Apr 12, 2019 at 1:49
  • 1
    void getData(int c;int *a,int r,int c) is a syntax error Commented Apr 12, 2019 at 2:30

1 Answer 1

3

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.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.