Thread: Multidimensional arrays

  1. #1
    Registered User
    Join Date
    Aug 2009
    Posts
    140

    Multidimensional arrays

    Hi all

    I am a little confused about multidimensional arrays. Please look at this

    Code:
    char mda[][10] = {"one", "two", "three"};
    Can you explain to me, why multidimensional arrays with characters must be defined like the above method? Why can't I just write

    Code:
    char mda[][] = {"one", "two", "three"},
    i.e. char (mda[])[] = {...}, so an array, where each element is an array?

  2. #2
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    When you index into a multi-dimensional array the compiler can't simply infer the offset into the data - it needs to know the dimensions a priori in order to calculate it. For example, let's say you want the character at mda[ 3 ][ 5 ]. The compiler has to know the distance between mda[ 2 ] and mda[ 3 ] before it can generate the offset. Without specifying the second dimension (eg: columns) this is essentially impossible. Consider now if you had declared it as char mda[][11]. When you ask for mda[ 3 ][ 5 ] the compiler calculates ( 3 * 11 ) + 5 and adds this to the base address of mda to locate the character.

    Incidentally, you can declare an array of pointers if you don't want to fuss with the second dimension:

    Code:
    char const* mda[] = {"one", "two", "three"};
    Just keep in mind that assigning a pointer to a string literal means that the data is read-only. If you need to write to the data, you'll need to allocate some memory to each pointer.

  3. #3
    Registered User
    Join Date
    Aug 2009
    Posts
    140
    Thank you for replying. May I ask how you got to "( 3 * 11 ) + 5"?

  4. #4
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Multidimensional arrays are laid out in order in memory, starting with [0][0], then [0][1], then [0][2], ..., [0][11], [1][0], [1][1], and so on. So every step in the first dimension is actually 11 steps (for your specific case) total to get through the entire row.

  5. #5
    Registered User
    Join Date
    Aug 2009
    Posts
    140
    Ok, in that case it should be ( 3 * 11 ) + 6, and not + 5, right?

    By the way, is a 1D-array a row of a column in C?

  6. #6
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    A row.

  7. #7
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by Niels_M View Post
    Ok, in that case it should be ( 3 * 11 ) + 6, and not + 5, right?
    No? You don't have to move any to get to the first element, because, well, that's where you already are.

  8. #8
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    Quote Originally Posted by Niels_M View Post
    Ok, in that case it should be ( 3 * 11 ) + 6, and not + 5, right?
    No, arrays use 0-based indexes, so + 6 would set it to the past the element by 1.

  9. #9
    Registered User
    Join Date
    Aug 2009
    Posts
    140
    I see. Thanks.

    When I pass a multidimensional array as a function parameter, then it is the address of the first element in the multidimensional array which is passed. In this case, this address points to an array (a row) as well.

    So when we write e.g. f ( int (*a)[5]), then this means that *a is an integer pointer, which points to an array (a row) containing 5 integers (five colums)?

    If the above is correct, then why is it that is it equivalent of writing f ( int a[][5])?
    Last edited by Niels_M; 09-05-2009 at 02:15 AM.

  10. #10
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    Quote Originally Posted by Niels_M View Post
    I see. Thanks.

    When I pass a multidimensional array as a function parameter, then it is the address of the first element in the multidimensional array which is passed. In this case, this address points to an array (a row) as well.

    So when we write e.g. f ( int (*a)[5]), then this means that *a is an integer pointer, which points to an array (a row) containing 5 integers (five colums)?

    If the above is correct, then why is it that is it equivalent of writing f ( int a[][5])?
    int (* a )[ 5 ] is a pointer to an array of an array of 5 elements (no, I am not repeating myself there!), if that makes sense. Had you declared it without parenthesis, it would have been an array of pointers to integers.

  11. #11
    Registered User
    Join Date
    Aug 2009
    Posts
    140
    Quote Originally Posted by Sebastiani View Post
    int (* a )[ 5 ] is a pointer to an array of an array of 5 elements (no, I am not repeating myself there!), if that makes sense. Had you declared it without parenthesis, it would have been an array of pointers to integers.
    But why is it that the compiler allows for the decleration f ( int a[][5] )? Is it because the compiler interprets the "a[]"-part as (*a)?

  12. #12
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    Yes. Consider a single-dimension array:

    Code:
    double values[16];
    Now you could pass it to either of these functions:

    Code:
    void foo( double* data, size_t length )
    {	}
    
    void bar( double data[ ], size_t length )
    {	}
    So the functions essentially have the same signature.

  13. #13
    Registered User
    Join Date
    Aug 2009
    Posts
    140
    Thank you. I have one last question, and it is related to the above.

    The following is not permitted in C

    Code:
    int *test = {1,2,3} // not permitted
    since {1,2,3} is an initializer list, and *test is a pointer. In C we know that when a function is called, the copies of the arguments are made as if by assignment. In post #9 I wrote

    Code:
    f ( int (*a)[5])
    where *a points to an array with 5 integer elements. Thus we are actually writing

    int (*a)[5] = {1,2,3,4,5}.

    Now, how can this paradox be explained?

  14. #14
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    Quote Originally Posted by Niels_M View Post
    Thus we are actually writing
    Code:
    int (*a)[5] = {1,2,3,4,5}.
    Now, how can this paradox be explained?
    We do no such thing, so no paradox here
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  15. #15
    Registered User
    Join Date
    Aug 2009
    Posts
    140
    Quote Originally Posted by vart View Post
    We do no such thing, so no paradox here
    I know that, but we know (as I wrote) that when a function is called, the copies of the arguments are made as if by assignment. So essentially what we have is

    Code:
    int (*a)[5] = {1,2,3,4,5}.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Multidimensional Arrays
    By jordanguyoflove in forum C Programming
    Replies: 4
    Last Post: 10-16-2008, 06:16 PM
  2. Multidimensional Arrays?
    By CreatedByShadow in forum C++ Programming
    Replies: 7
    Last Post: 01-13-2006, 10:35 PM
  3. Pointers to Multidimensional Arrays
    By kidburla in forum C Programming
    Replies: 10
    Last Post: 10-29-2005, 10:45 PM
  4. Multidimensional arrays in Korn shell
    By Yasir_Malik in forum Tech Board
    Replies: 3
    Last Post: 04-11-2004, 02:16 PM
  5. Passing multidimensional arrays to functions
    By maxthecat in forum C Programming
    Replies: 3
    Last Post: 12-22-2001, 03:58 PM