-2

Going through knr and i've reached multidimensional arrays.

I'm wondering about a couple things:

First.

Suppose i initialize the following array

int a[2][4] = {{1,2,3},{4,5,6}};

Now, i understand this as setting aside 2 blocks of 4*sizeof(int) bytes of contiguous memory. Alright, so then it seems to me like its just a nice way to set aside memory defined multiplicativly. So... Why is the following not true:

int a[8] == int[2][4]

Second, when i go,

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

Why does this attempt fail

a[5] = 22;

So what IS a multidimensional array if its not just a contiguous block of memory?

captaincurrie
  • 157
  • 1
  • 1
  • 7
  • 1
    `int a[2,3]` won't compile. – alk May 01 '14 at 18:44
  • captaincurrie, perhaps you should edit your question detail and fix int a[2, 3]? (as found by alk) – Mahonri Moriancumer May 01 '14 at 18:48
  • 1
    `int a[8] == int[2][4]` is also not legal C – turbulencetoo May 01 '14 at 18:48
  • where in the c standard does it say a 2D array will have all elements stored in a contiguous block of memory? – Red Alert May 01 '14 at 18:49
  • @RedAlert If 1D arrays are guaranteed to be contiguous, then a 1D array that contains arrays should also surely be contiguous. – turbulencetoo May 01 '14 at 18:53
  • 1
    `int a[2,3]` is the same as `int a[3]`, unfortunately. – Dietrich Epp May 01 '14 at 19:01
  • possible duplicate of [Confusion about pointers and multidimensional arrays](http://stackoverflow.com/questions/3911244/confusion-about-pointers-and-multidimensional-arrays) with a nice answer here: http://stackoverflow.com/a/3963467/694576 – alk May 01 '14 at 19:04
  • 1
    @DietrichEpp: I also thought of this, but a quick test revealed that at least gcc 4.7.2 rejects it with the error `expected ‘]’ before ‘,’ token`. – alk May 01 '14 at 19:07
  • @DietrichEpp int a[2,3] is a syntax error, i fixed it about – captaincurrie May 01 '14 at 19:08
  • @RedAlert K&R 2nd Edition. In sections A7.3.1, "The expression E1[E2] is identical (by definition) to *((E1)+(E2))." In section A8.6.2, "It follows from the rules that arrays are stored by rows (last subscript varies fastest)..." – user3386109 May 01 '14 at 19:36
  • @user3386109 that applies to 1D arrays. `E1[E2][E3]` is not identical to `*(E1 + E2 + E3)`. You need to deference twice for a 2d array - `*(*(E1 + E2) + E3)` – Red Alert May 01 '14 at 19:45
  • @RedAlert See section A8.6.2 for details. It's too long to quote here in its entirety. – user3386109 May 01 '14 at 19:55
  • @captaincurrie: Ah, I thought it would have been parsed the same as `int a[(2,3)]`. – Dietrich Epp May 01 '14 at 20:17

3 Answers3

0
T a[x][y][z];

ais an array (with x elements) of arrays (with y elements each) of arrays (with z elements each) of type T.

Update:

An array defined as above indeed is a continous block of memory.

However seeing a line like this

T t = b[0][0[0];

without knowing how a is defined does not necessarily mean b is a continous block of memory holding all elements accessable via indexing b in 3 dimensions.

Arrays can be scattered.

For example

T ** c1 = malloc(x * sizeof(*c1));
for (size_t i = 0; i < x; ++i)
  c1[i] = malloc(y * sizeof(**c1));

would allow you to access c1's x*y elements in exactly the same way as you could do with

T c2[x][y];

c2 elements are stored in one continous region of memory, whereas c1 elements are scattered in x regions of size y, with an addtional block of memory of size c1 is x * sizeof(*c1) compared to the size of c2.

alk
  • 69,737
  • 10
  • 105
  • 255
  • These are C arrays, not high-level python arrays. My confusion is born from the 'low-level' arrays in C; "contiguous blocks of memory", not super abstract objects. Is that interpretation wrong for multidimensional arrays? Thats what i'm really wondering – captaincurrie May 01 '14 at 19:06
  • "high-level", "low-level", "Python" ...? - I don't get you? There is only one way to declare an array in C. @captaincurrie – alk May 01 '14 at 19:10
  • I feel that in higher level language, like Python, arrays are much more abstract objects, because they behave that way. Whereas in C, you can't use arrays without understanding there 'low-level' "reality" as 'contiguous blocks of memory'. My confusion is born from failing to understand the low-level reality of C multidimensional arrays – captaincurrie May 01 '14 at 19:15
0

If you have int a[2][4] and you try to access a[1], the a[1] is an int[] and not an int.

In other words a[1] is an array while a[1][1] is an integer value.

You need to cast in order to do what you want.

daouzli
  • 15,288
  • 1
  • 18
  • 17
0

A multidimensional array is just a contiguous block of memory. However, when you declare a variable, the compiler expects you to use that variable as you've declared it. So if you declare a as a two dimensional array with the line

   int a[2][4] = {{1,2,3},{4,5,6}};

then the compiler is going to treat the variable a as a two dimensional array.

If you would like to access that array as a one dimensional array, then you need to declare another variable, e.g.

   int *b = (int *)a;

Then you can access the elements of the array with code like this

   for ( i = 0; i < 8; i++ )
       printf( "%d %d\n", i, b[i] );

and the output will be

0 1
1 2
2 3
3 0
4 4
5 5
6 6
7 0

Note the zeros at locations 3 and 7. Those elements are zero because each row of the array was declared to hold 4 items, but the initializer only has 3 items per row. Any unspecified items in the initializer are filled with zeros.

user3386109
  • 34,287
  • 7
  • 49
  • 68