2

I'm very confused about this question in C.

if a[i] is equivalent to *(a+i). What is the equivalent of a[j][i]?

I know the (a+i) is incrementing the memory address of the first element of the array by the value of i and then using the * operator to dereference that address to obtain the value. However, I am confused about multidimensional arrays. In memory, the values are stored just like a single dimensional array but I don't understand how I can increment the memory address by using the variable i or j like in the single dimensional array example.

for some reason printing *a in single dimensional array will print the first element of the array whereas *a in a multidimensional array will print a random number. Why is this so?

Any help is greatly appreciated.

Deb
  • 2,922
  • 1
  • 16
  • 32
Mishy
  • 97
  • 1
  • 2
  • 10
  • This could *rapidly* degenerate into a full-blown tutorial on pointers, arrays, pointer arithmetic, array striding, and I can see an easy tangent into pointer-arrays. Some time on the business end of [**a good C text**](http://stackoverflow.com/questions/562303/the-definitive-c-book-guide-and-list) and reviewing [questions like **this one**](http://stackoverflow.com/questions/5727/what-are-the-barriers-to-understanding-pointers-and-what-can-be-done-to-overcome) would do you some serious good. – WhozCraig Sep 19 '14 at 06:33

4 Answers4

4

if a[i] is equivalent to *(a+i). What is the equivalent of a[j][i]?

 a[j][i] 

is similar to

 *(*(a+ j) + i)

Now If you want to know how it is?

Then let see

You already know that

a[j]=*(a+j)            -------------------------> res 1

Now

a[j][i] = *(a[j]+i);   --------------------------> res2

After that replace the res1 in res2. So it become

a[j][i] = *(*(a+ j) + i)   ----------------------> res3
Jayesh Bhoi
  • 24,694
  • 15
  • 58
  • 73
  • Thanks! However, I still dont quite understand it conceptually. within the parenthesis you dereference *(a+i) before adding the int j to it and then dereference it again. How does this work if the result is dependent on the value of what is at the i index (a[i]) rather than the address itself? – Mishy Sep 19 '14 at 06:28
  • @Mishy For you clarification see link http://stackoverflow.com/questions/6673719/memory-map-for-a-2d-array-in-c – Jayesh Bhoi Sep 19 '14 at 06:54
  • This answer will be complete with the assertions of @newacct below – Luis Colorado Sep 22 '14 at 06:50
2

The literal answer to the question is simple: a[i] is defined to be always identical to *(a+i) by the standard, and therefore, a[j][i] is guaranteed to be always identical to *(*(a+j)+i). However, that by itself does not help us to understand what is going on; it just transforms one compound expression to another.

a[j][i] (and by extension, *(*(a+j)+i)) does very different things depending on the type of a. This is because, depending on the types, there may be implicit array-to-pointer conversions that are not apparent.

In C, a value of array type T[x] is implicitly converted to an rvalue of pointer type T* in many contexts, some of which include the left side of the subscript operator, as well as an operand in addition. So if you do either a[i] or *(a+i), and a is an expression of array type, in both cases it is converted to a pointer to its first element (like &a[0]) and it's the pointer that participates in the operation. Thus you can see how *(a+i) makes sense.

If a had type T[x][y], it would be a "true" multidimensional array, which is a C array whose elements are themselves C arrays (of a certain compile-time-constant size). In this case, if you consider *(*(a+j)+i), what is happening is 1) a is converted to a pointer to its first element (which is a pointer to an array, of type T(*)[y]), 2) that pointer is incremented and dereferenced, producing a value of array type (the jth subarray of a), 3) that array is then converted to a pointer to its first element (a pointer of type T*), which is then 4) incremented and dereferenced. This finally produces the ith element of the jth element of a, what you usually think of as a[j][i].

However, a could also have type, say, T**. This is usually used to implement "fake" multidimensional arrays, which is an array of pointers, which then in turn point to the first element of some array. This allows you to have "rows" that can have different sizes (thus the multidimensional array need not be "rectangular"), and sizes not fixed at compile time. The "rows", as well as the main pointer array, do not have to be stored contiguously. In this case, if you consider *(*(a+j)+i), what is happening is 1) a is incremented and dereferenced, producing a value of pointer type (the jth element of a), 2) that pointer is then incremented and dereferenced. This finally produces the ith element of the array referred to by the jth element of the main pointer array. Note that in this case there are no implicit array-to-pointer conversions.

newacct
  • 119,665
  • 29
  • 163
  • 224
1

Generally array follows pointer concepts.For 1D array one time dereference is enough to get value.But in multidimensional array ,to get values we have dereference 2times in 2D array, 3times in 3D array like that.

In a[j][i]=*(*(a+j)+i)

Anbu.Sankar
  • 1,326
  • 8
  • 15
0

A multidimensional array in C is contiguous. The following:

int a[4][5];

consists of 4 int[5]s laid out next to each other in memory.

An array of pointers:

int *a[4];

is jagged. Each pointer can point to (the first element of) a separate array of a different length.

a[i][j] is equivalent to ((a+i)+j). See the C11 standard, section 6.5.2.1:

The definition of the subscript operator [] is that E1[E2] is identical to (*((E1)+(E2)))

Thus, a[i][j] is equivalent to (*(a+i))[j], which is equivalent to ((a+i)+j).

This equivalence exists because in most contexts, expressions of array type decay to pointers to their first element (C11 standard, 6.3.2.1). a[i][j] is interpreted as the following:

a is an array of arrays, so it decays to a pointer to a[0], the first subarray.
a+i is a pointer to the ith subarray of a.
a[i] is equivalent to *(a+i), dereferencing a pointer to the ith subarray of a. Since this is an expression of array type, it decays to a pointer to a[i][0].
a[i][j] is equivalent to *(*(a+i)+j), dereferencing a pointer to the jth element of the ith subarray of a.

Note that pointers to arrays are different from pointers to their first element. a+i is a pointer to an array; it is not an expression of array type, and it does not decay, whether to a pointer to a pointer or to any other type.

and for some reason printing *a in single dimensional array will print the first element of the array whereas *a in a multidimensional array will print a random number. Why is this so? 

for two dimensional array you need to dereference it accordingly ,

printf("\nvalue : %d",**a);

to print the first element of the array.

PU.
  • 148
  • 9