LordObnoxious
LordObnoxious

Reputation: 117

Accessing elements of 2D array using pointers

I was going through the passage pertaining to the access of individual elements of a 2D array using pointers.

It suggests the following mechanism to access the ith row's jth element of the 2D array arr[5][5]:

*(*(arr+i)+j)

From my cursory understanding of pointers, I am given to understand that the name of the array yields the address of the 0th element of the 0th row, and that any integral increment to the array will yield the base address of the next row. All's fine till this juncture, I suppose.

However, what I fail to understand is the relevance of the indirection (*) operator within the following snippet:

*(arr+i)

How is the indirection operator in this case relevant? Since the name of the array itself yields the base address of the 0th row, adding any integral number to it entails it to point to the base element of the next row. In that case, the following snippet yields the address of the ith row:

(arr+i)

And the addition of j warrants the pointer to point to the jth element of the said row.

However, in the following snippet:

*(arr+i)

Wouldn't the addition of the indirection operator cause it to yield the ith element of the row, as opposed to the address of the base element of the ith row?

Should not the following be the code to access the ith row's jth element?

*((arr+i)+j)

In the aforementioned case, incrementing arr i times will entail the code fragment (arr+i) to point to the base address of the ith row, and then the addition of j will entail the address of the ith row's jth element, and then the indirection operator (*) would yield the element that the specific address holds, wouldn't it?

Is my reasoning satisfactory?

Upvotes: 2

Views: 1110

Answers (3)

user16719198
user16719198

Reputation:

*((arr+i)+j)

The parentheses around (arr+i) are mathematically unnecessary, but they are not enough to switch dimensions from rows to elements. i is for rows, j for elements, and it is a good idea to group them, but it takes *(...).

With *(arr + i + j) it seems obvious that i and j are on the same level.

Upvotes: 0

Vlad from Moscow
Vlad from Moscow

Reputation: 310930

From my cursory understanding of pointers, I am given to understand that the name of the array yields the address of the 0th element of the 0th row, and that any integral increment to the array will yield the base address of the next row. All's fine till this juncture, I suppose.

It is not exactly how you think.

An array designator used in an expression is implicitly converted (with rare exceptions) to a pointer to its first element.

If you have a two-dimensional array like for example

T arr[M][N];

(where T is some type specifier) then the array designator arr is converted to a pointer of the type T ( * )[N] that points to the first element of the array arr[0] having the type T[N].

Of course the value of the pointer is equal to the value of the address of the first element arr[0][0] of the type T.

So let's consider the expression

*(*(arr+i)+j)

In this expression the array designator arr is converted to pointer to the first element of the array. That is the expression arr yields the value of the expression &arr[0]. The expression arr + i yields the value &arr[i]. Dereferencing the expression like *( arr + i ) you will get one dimensional array arr[i] that in turn used in the expression *( arr + i ) + j is converted to a pointer to its first element of the type T * that is equivalent to the expression &arr[i][0] . And due to adding the variable j the pointer points to the element &arr[i][j]. Dereferencing this expression like

*(*(arr+i)+j)

that is equivalent to the expression &arr[i][j] you will get the element arr[i][j].

Upvotes: 1

Joshua
Joshua

Reputation: 43197

The ith/jth element should be accessed using

arr[i][j]

but if for some reason you had to do it the hard way it would be

*((type *)arr + i * 5 + j)

where the 5 is the number of columns in the array. The problem with

*((arr+i)+j)

is arr is of the wrong type and things break down. In theory, the following should work but I never tried anything like it:

*((type *)(arr+i)+j)

But from here we are in a position to discuss

*(*(arr+i)+j)

again; I have never tried this; just the rectangular form at the top. But we should be able to understand this. Type of arr is type[][] which is convertible to type[]*; thus it the result of *(arr + i) should be the ith row as type type[] which is convertible to type*; thus we should expect *(*(arr+i)+j) to access the ith row of the jth column. Without the inner deference we would end up with the (i+j)th row instead.

Note that arr must be declared correctly or it's going to interpret it as pointer to pointer rather than pointer to array and do the wrong thing.

Upvotes: 0

Related Questions