-1

This code should read and display a matrix. But it doesnt work, I cant find the problem. Why it doesnt work?

#include <stdio.h>

#define MAX 100

void read_matrix(int a[MAX][MAX], int n)
{
    int i, j;

    scanf("%d", &n);
    for (i = 0; i < n; i++)
        for (j = 0; j < n; j++)
            scanf("%d", &a[i][j]);
}

int main(void)
{
    int a[MAX][MAX], n = 1, i, j;

    read_matrix(a, n);

    for(i = 0; i < n; i++) {
        for (j = 0; j < n; j++)
            printf("%d ", a[i][j]);
        printf("\n");
    }

    return 0;
}

For input:

2
1 2
3 4

The output is:

1
DanielC
  • 13
  • 1
  • 6
  • Do some research about *emulate pass by reference in C*. – Some programmer dude Dec 05 '17 at 09:08
  • 3rd time someone asks this question today. Is there a canonical duplicate for "Why doesn't my main program work when I alter local variables inside a function only?" Close one but not quite a duplicate: [Dynamic memory access only works inside function](https://stackoverflow.com/questions/39486797/dynamic-memory-access-only-works-inside-function) – Lundin Dec 05 '17 at 10:08

2 Answers2

2

Because n is passed by value, not by reference. Use:

void read_matrix(int a[MAX][MAX], int *n) {
    int i, j;

    scanf("%d", n);
    for (i = 0; i < *n; i++)
        for (j = 0; j < *n; j++)
            scanf("%d", &a[i][j]);
}

and

read_matrix(a, &n);

Now n is passed by reference and it should work as expected.

Ctx
  • 18,090
  • 24
  • 36
  • 51
0

First of all, let's deal with a fact "In C there is nothing called pass by reference".

But yes we emulate that with what is available in C, that is pass by value.

So in the first case there are things that happened

  • You call the function like this read_matrix(a, n);

  • A copy of the variable is there in read_matrix.

  • We make changes to the copy.

  • Function ends and story ends there. That local variable's scope ends. It is not alive now.

  • You come back to main(). Do you expect to see any change in n? Nope. Because all change was there in read_matrix.

Now to change that we write it this way.

void read_matrix(int a[MAX][MAX], int* nn)
{
    if( scanf("%d", nn) != 1){
        fprintf(stderr,"Error in input");
        exit(1);
    }
    for (size_t i = 0; i < *nn; i++)
        for (size_t j = 0; j < *nn; j++)
            if( scanf("%d", &a[i][j]) != 1){
                fprintf(stderr,"Error in input");
                exit(1);
            }
}

Now here also couple of things happened

  • You pass the &n or the address of n.

  • Then nn is a local variable (local to read_matrix) containing the address of n.

  • scanf() wants the address of what it will write something.

  • We pass the address of n or content of nn.

  • Then scanf() writes where? In the memory of n. So n in main() changes.

  • Now we want to get while looping the value of n or the value in address of n or the value in the address contained by nn.

  • So we use * on nn. Or *nn.

  • Now you back to main() and the local variable nn is not there and it's lifetime ended when the function read_matrix ended.

  • You see the changed value in n.


Do you see any difference in two method?

In one we pass the value. In another we pass as value the address of n.

Both are pass by value. But in second method due to the side effect of accessing memory we see he change in main(). Story ends.

Community
  • 1
  • 1
user2736738
  • 30,591
  • 5
  • 42
  • 56