1

Possible Duplicate:
How do I use arrays in C++?

One dimensional array as a function parameter:

#include <stdio.h>
#include <string.h>

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

int main(void)
{   
    int a[2] = {1,2};
    func(a, 2);
}

it compiles and runs correctly.

But when a two-dimensional array as a function parameter:

#include <stdio.h>
#include <string.h>

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

int main(void)
{   
    int a[2][2] = {{1,2}, {3,4}};
    func(a, 2);
}

it can not compile correctly. I must modify the code like this:

#include <stdio.h>
#include <string.h>

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

int main(void)
{   
    int a[2][2] = {{1,2}, {3,4}};
    func(a, 2);
}

I do not know why? Anybody can explain how it works? Many thanks.

2
  • int a[] then a[i][j] - How on Earth does this compile correctly? Commented Jan 1, 2013 at 17:02
  • This question is not a duplicate of "How do I use arrays in C++". That question is so broad anyway (so poorly phrased). This question is more specific (although in need of some editing for English-correctness). Also, even though some of what is addressed in that question relate to here, they are often specific to C++ whereas this question should be limited to C and be oriented toward C idioms. If this is a duplicate of another question on SO, let's get the correct one listed here. Commented Feb 4, 2015 at 16:17

5 Answers 5

7

Arrays (both one and multidimensional) in c reside in continuous memory blocks. This means that when you define char a[3], the array is laid out in memory like this (forgive my terrible ascii art skills):

| a[0] | a[1] | a[2] |

For a two-dimensional array char a[2][3], the layout is like this:

| a[0][0] | a[0][1] | a[0][2] | a[1][0] | a[1][1] | a[1][2] |  
                              ^
                              +--- first row ends here

Therefore, when you index into a two-dimensional array a[i][j], the compiler generates code equivalent to this:

*(a + i*3 + j)

Which can be read as "skip i rows and take cell j in that row". To accomplish this, the compiler must know the length of the row (which is the second dimension). This means that the second dimension is a part of the type definition!

As such when you want pass a 2d array into a function, you must specify the needed dimension for the type definition.

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

Comments

3

Recent (e.g. C2011, and perhaps C99) C standards enable variable length array so the following function does work

int
sum (int n, int t[n][n])
{
  int s = 0;
  for (int i = 0; i < n; i++)
    for (int j = 0; j < n; j++)
      s += t[i][j];
  return s;
}   

this is compiled without warnings with gcc-4.7 -std=gnu99 -Wall -O -c ex.c and the generated assembler is what you expect

As to why int t[][] cannot work, it is because each element of the entire t would be of type int [] which has indeterminate size.

Comments

0

Here is a quite good explaintation: http://www.eskimo.com/~scs/cclass/int/sx9a.html

Comments

0

Without the second dimension to the array the compiler doesn't know how to index into it. This is because the compiler does some arithmetic with a pointer to work out where to find the value in memory.

Comments

0

Arrays in C are quite "weak", and typically represented at run-time by just a pointer to the first element. When you declare something like int a[][], it's not possible to know how to compute the address of each element, since the type declaration doesn't say. This is why it won't compile, since the type is invalid.

If you could have int a[][], and then called it passing either int big[8][8] or int small[2][2], there's no way for the code inside the function to magically "adapt" for the proper address computation for these different arrays. This is why it won't work.

You can write a general function like int *matrix, size_t width and do the address computation manually, i.e. element "matrix[i][j]" is at matrix[i * width + j] for a row-major ordering.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.