How to define a pointer to multiple-subscripted arrays

Discussion in 'C Programming' started by Zhou Yan, Mar 8, 2007.

  1. Zhou Yan

    Zhou Yan Guest

    I want to define a pointer to a multiple-subscripted array.
    For instance, I have an array defined as below( I have reduced the
    size of the array as well as the dimension, but I think it OK to ask
    this simple case.)

    /----
    int array[ 2 ][ 2 ] = { 1, 2, 3, 4 }

    \-----

    Now I want a pointer to point to this array.

    I tried blow
    /----
    #include <stdio.h>
    int main()
    {
    int array[ 2 ][ 2 ] = {
    1, 2,
    3, 4
    };

    int *nPtr[ 2 ];

    nPtr = array;
    printf( "%d\n", nPtr[ 1 ][ 1 ] );
    return 0;
    }
    \----

    when compilation, the compiler say:

    main.c:11: warning: assignment from incompatible pointer type
    main.c:13: error: subscripted value is neither array nor pointer
     
    Zhou Yan, Mar 8, 2007
    #1
    1. Advertisements

  2. Zhou Yan

    Daniel Guest

    Yes, nptr is an array having two pointer members which points to int
    type;
    however, array is a two dimension array. They have different
    type.
    changing statement "nptr = array;" to "nptr[1] = &array[1][0];" may
    work...
     
    Daniel, Mar 8, 2007
    #2
    1. Advertisements

  3. Zhou Yan

    Zhou Yan Guest

    thanks, I try now...
     
    Zhou Yan, Mar 8, 2007
    #3
  4. Zhou Yan

    Zhou Yan Guest

    Yes, by this changing, it work properly. But I still do not
    understand. Could you kindly give a brief explanation?

    Also I tried to print all the 4 numbers and I followed this way, I
    find I also need:

    nPtr[ 0 ] = array[ 0 ];

    and I checked array[ 0 ] is just the same as &array[ 0 ][ 0 ] by

    printf( "%p\n%p\n", array[ 0 ], &array[ 0 ][ 0 ] );
    printf( "%p\n%p\n", array[ 1 ], &array[ 1 ][ 0 ] );

    Could you please kindly give me a explanation?
    What is array[ 0 ] actually is? Is it an array which contain the the
    first row of this array? Or is it a pointer, with the address of array[
    0 ][ 0 ]. Or internally it is both?

    If I define such an array of pointers, nPtr[ 2 ], I need to initialize
    all the pointers in this array,right? Is it possible to define a
    single array which can point to any address of a 2-D array? (I need to
    ask such silly quetions...but I really know nothing and cannot find a
    book talk about these)

    Thank you
     
    Zhou Yan, Mar 8, 2007
    #4
  5. Zhou Yan

    mhagerty Guest


    Change: int *nPtr[2]; // declares an array of 2 pointers to ints
    To: int (*nPtr)[2]; // declares a pointer to an array of 2 ints

    Recompile, run. The difference is subtle, but the result it totally
    different.

    http://www.cs.cf.ac.uk/Dave/C/node10.html

    Matthew
     
    mhagerty, Mar 8, 2007
    #5
  6. The full explanation is below.
    address of a 2-D array?

    Well, you got one answer on how to get a segment of the array, now for
    the full explanation:

    An 2D array (as you have allocated) is not an array of pointers to an
    array of elements, it is in fact a bunch of elements allocated in one chunk.

    array is of type int[][2] and is convertible to a pointer to an array of
    two elements (int (*)[2]). You can declare a variables of this type
    like this:

    // Get from zeroth 'row' on down
    int (*var0)[2] = array; // or
    int (*var0)[2] = array+0; // or
    int (*var0)[2] = &array[0];
    // Get from first 'row' on down
    int (*var1)[2] = array+1; // or
    int (*var1)[2] = &array[1];

    Note: not int *var[2] as this is an array of int pointers of two
    elements. Note also that you cannot cast to or define this type this
    directly, something in the language/parser prevents this. To
    cast/return, you need to generate a typedef like so:

    typedef (*ptrToTwoElementArray_t)[2];

    (something that I just figured out now, thanks to you. That has
    been bugging me forever, as I've never been able to return or cast
    to something like this. Thanks very much!)

    array[0] is of type int[] and is convertible to a pointer to an array of
    elements (int *). You can also declared a variable of this type
    like this:

    // Get zeroth 'row'
    int *var0 = *(array);
    int *var0 = *(array+0);
    int *var0 = array[0];
    // Get first 'row'
    int *var1 = *(array);
    int *var1 = *(array+1);
    int *var1 = array[1];

    This is why your code:

    printf( "%p\n%p\n", array[ 0 ], &array[ 0 ][ 0 ] );
    printf( "%p\n%p\n", array[ 1 ], &array[ 1 ][ 0 ] );

    gave you the results that you found.

    array[0][0] is of type int and is convertible to an int. You can also
    declare a variable of this type like this:

    int var = array[0][0];

    This should be obvious.

    When you dereference an array (declared as you described) using the []
    operators, the compiler knows that this is not an array of pointers to
    an array of ints, but that it is a big blob of ints and that it can
    calculate the offset to the ints via the formula x+y*MaxX.
    Don't think your question silly. I've been trying to figure this out
    for 20 years. :) The only silly question is the unasked one. I
    certainly learned something from answering this question, I hope that I
    explained it sufficiently for you to too.


    Adrian
     
    Adrian Hawryluk, Mar 9, 2007
    #6
  7. Zhou Yan

    Zhou Yan Guest

    Thank you very much for you explanation. I will print this message
    out to read a few times to get the whole idea...

    Thanks!
     
    Zhou Yan, Mar 9, 2007
    #7
  8. Hi Zhou Yan,

    Would you mind if I used your name in my blog? I would like to credit
    the question to you.


    Adrian
     
    Adrian Hawryluk, Mar 9, 2007
    #8
  9. I don't blame you, I certainly took me a while to figure it out. :)


    Adrian
     
    Adrian Hawryluk, Mar 9, 2007
    #9
  10. Zhou Yan

    Zhou Guest

    It's of course Ok... You helped me so much...
    But perhaps, I hope you can use "Matthew Zhou" or "Matthew", my
    English name instead of my Chinese Name. -:)
     
    Zhou, Mar 9, 2007
    #10
  11. Zhou Yan

    Thad Smith Guest

    The original code defined nPtr as an array, size 2, of pointer to int.
    Adding the parentheses defines nPtr as a pointer to an array, size 2, of
    int, which is compatible with an array of arrays (length 2) of int.

    The first index then selects the row, while the second selects the
    element within the row.
     
    Thad Smith, Mar 9, 2007
    #11
    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.