0

I have a question regarding passing an array to another function.

#include <stdio.h>
void print (int ar[]);

main () {
    int array[2][2] = {1,2,3,4};
    print(array);
}

void print (int ar[]) {
    printf("%d\n", ar[0]);
    printf("%d\n", *(ar+1));
}

So let's say if i'm passing array to function print. Am I passing address of the first 1-D array (array[0]) or am i just passing the address of the very first variable (array[0][0]).

And as for the print function, in this case, am I correct to say that by printing ar[0], I am printing array[0][0]?

But why is it that for the case of printing *(ar+1), I am actually printing array[0][1] instead of array[1][0]?

Thank you everyone in advance!

Luna
  • 73
  • 1
  • 1
  • 7

4 Answers4

2

If you are passing a two-dimensional array to a function:

int array[NROWS][NCOLUMNS];
print(array);

the function's declaration must match:

void print(int array[][NCOLUMNS])
{ ... }

or

void print(int (*ap)[NCOLUMNS]) /* ap is a pointer to an array */
{ ... }

The 2D arrays which is array of arrays decays a pointer to an array rather than a pointer to a pointer.

Sunil Bojanapally
  • 12,528
  • 4
  • 33
  • 46
1

So let's say if [I]'m passing array to function print. Am I passing address of the first 1-D array (array[0]) or am [I] just passing the address of the very first variable (array[0][0]).

You are passing a pointer to the first element of array, array[0], which is itself an array. That pointer has the same value as a pointer to array[0][0], but different type. In fact, your code is incorrect in that the argument's type and the function parameter's type do not agree, but as long as the types int(*)[] and int * have the same representation, the reinterpretation will work in practice.

And as for the print function, in this case, am I correct to say that by printing ar[0], I am printing array[0][0]?

Yes, when you call print() as you do in your example, provided that type representations agree as described above.

But why is it that for the case of printing *(ar+1), I am actually printing array[0][1] instead of array[1][0]?

Because ar is a pointer to the first element of array, i.e. the 1D array array[0]. Its elements are array[0][0], array[0][1], etc.. ar + 1 is therefore a pointer to the second element of array[0], which is array[0][1].

You have two options to make your code correct, both of which might help clarify the issues involved. You could change the argument you pass to print() to agree with the function:

print(array[0]);

Alternatively, you could change the declared type of print()'s argument, whith a corresponding alteration to its use:

void print(int (*ar)[2]) {
    printf("%d\n", ar[0][0]);
    printf("%d\n", *(ar+1)[0]);
}

or

void print(int ar[][2]) {
    printf("%d\n", ar[0][0]);
    printf("%d\n", *(ar+1)[0]);
}

The latter two change the meaning of *(ar + 1).

John Bollinger
  • 160,171
  • 8
  • 81
  • 157
  • `void print(int (*)[*])`? – EOF Sep 02 '15 at 14:15
  • Well done actaully answering the question instead of just telling the op the mistake in their code. +1 – Mic1780 Sep 02 '15 at 14:15
  • @EOF, yes, that should work too, provided you're not limited by a requirement for C90 compliance. I imagine that's not an issue for most people. – John Bollinger Sep 02 '15 at 14:21
  • @EOF, or at least it works for argument agreement. It does not work if you want to be able to evaluate `ar + 1`, because that requires `*ar` to have fixed, statically-known size. – John Bollinger Sep 02 '15 at 14:28
  • Thank you @JohnBollinger for the help. So essentially, I am passing the wrong type to the print function. – Luna Sep 03 '15 at 11:09
  • @Luna, the type of your actual argument does not match the declared type of the function parameter, yes. This is a problem with your code, yes -- its behavior is formally undefined, though in practice it can pretty reliably be expected to behave consistently, as described. If you make one of the latter two changes, then the (updated) second `printf()` call will print the value that can be accessed in `main()` as `array[1][0]`. If that all is what you mean by "essentially", then overall, yes. – John Bollinger Sep 03 '15 at 14:53
0

Your code is probably not doing what you want. Compile with Wall and you will see some warnings.

You need to change print argument to accept a 2D array (now you are passing int (*)[2] but the function is expecting int *), and then you can print the values correctly.

#include <stdio.h>
void print (int ar[][2]);

int main () {
    int array[2][2] = {
        {1,2},
        {3,4}
    };
    print(array);
    return 0;
}

void print (int ar[][2]) {
    printf("%d\n", ar[0][0]); // 1
    printf("%d\n", ar[1][0]); // 4
}
hlscalon
  • 7,304
  • 4
  • 33
  • 40
0

When you pass an array to a function, you are using "pass-by-reference" meaning you pass the address of the array.

  • Am I passing address of the first 1-D array (array[0]) or am i just passing the address of the very first variable (array[0][0]).

No. The way you are passing array currently you are giving the function the 2-D array.

  • And as for the print function, in this case, am I correct to say that by printing ar[0], I am printing array[0][0]?

No. You still need to specify the number you want to print from ar[0]

  • But why is it that for the case of printing *(ar+1), I am actually printing array[0][1] instead of array[1][0]?

This is because you are telling the program to go to array in memory and use pointer arithmetic to traverse the array. For example, if you have a char * str variable that contains characters abcde\0 and want to get the character at position 2 you can either do str[2] or *(str+2) which means the same thing and both give the character 'c'.

Mic1780
  • 1,774
  • 9
  • 23