Multidimensional arrays

Discussion in 'C Programming' started by whisper, Oct 22, 2004.

  1. whisper

    whisper Guest

    Hi: there is an issue that confuses me and the FAQ did not clarify it
    for me.
    (Sorry I am just learning!)

    Let say I define a multidimensional array in my main routine as
    follows:

    int arr[2][3]={{0,1,2}, {3,4,2}};

    and I pass the array as a parameter to a function declared by:

    int getsum(int arr[][], int numrows, int numcols)

    by calling getsum(arr,2,3) (getsum tries to sum up all the elements).

    I know that this is illegal, but I don't quite understand why.

    When arr is created (at compile time), we know exactly what its row
    width
    and column width are. So why do we have to pass that information to
    getsum ?


    Thanks
     
    whisper, Oct 22, 2004
    #1
    1. Advertisements

  2. What is? Calling getsum()?
    Because 'arr' is effectively a pointer from getsum's perspective. Thus,
    sizeof will only tell you how big the pointer is, not the object it points
    to. If you do this:

    struct Array
    {
    int arr[2][3];
    };

    int getsum(struct Array *pArr)
    {
    int arraySize = sizeof pArr->arr;

    /* ... */

    return 0;
    }
     
    Mark A. Odell, Oct 22, 2004
    #2
    1. Advertisements

  3. whisper

    Dan Pop Guest

    Because getsum doesn't have it. All it has is the address of a
    one-dimensional array of 3 int's. The getsum definition that minimises
    redundancy is:

    int getsum(int arr[][3], int rows)
    {
    int cols = sizeof arr[0] / sizeof arr[0][0];
    ...
    }

    It is only in C99 that you can do better than that and avoid having to
    hard code the number of columns in the function definition:

    int getsum(int rows, int cols, int arr[][cols]) { ... }

    Note that cols must be declared before being used, so the following is
    not allowed:

    int getsum(int arr[][cols], int rows, int cols) { ... }

    Of course, you can also specify the number of rows, but the compiler will
    simply discard this information:

    int getsum(int rows, int cols, int arr[rows][cols]) { ... }

    Dan
     
    Dan Pop, Oct 22, 2004
    #3
  4. whisper

    Dan Pop Guest

    Now, you have managed to hardcode both dimensions of the array, instead of
    the only one required by the C89 standard...

    Dan
     
    Dan Pop, Oct 22, 2004
    #4
  5. whisper

    Malcolm Guest

    Most beginners' books introduce multidimensional arrays at the same time as
    single-dimensional arrays, and quite early. This is a mistake since
    multidimensional arrays in C are an advanced feature. You can of course use
    a mutli-dimensional array in the function it was declared quite simply, but
    passing the array to a subroutine is complex.
    It is illegal because C passes the array as a raw address. Without column
    information, it has no way of resolving an expression such as arr[1][1].
    Because C is so close to assembler, it doesn't package variables with extra
    information, like bounds or type or array dimensions. Another language would
    allow you to do what you want, but not C.
     
    Malcolm, Oct 22, 2004
    #5
  6. The FAQ is obsolete.
    int getsum(size_t numrows, size_t numcols,
    arr[numrows][numcols]) {
    int total = 0;
    for (size_t i = 0; i < numrows; ++i)
    for (size_t j = 0; j < numcols; ++j)
    total += arr[j];
    return total;
    }
    int total = getsum(2, 3, arr);
    So that getsum knows what they are?
     
    E. Robert Tisdale, Oct 24, 2004
    #6
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.