Xavier Tan
Xavier Tan

Reputation: 53

C programming address for 2d array

If I initialized a 2d array let’s say

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

Is a[0] == &a[0]??

I know a[0] refers to the address for the first element of the array. So is &a[0] still the address?

Upvotes: 0

Views: 1013

Answers (4)

Eric Postpischil
Eric Postpischil

Reputation: 222933

There are two senses in which you might ask whether a[0] equals &a[0]:

Do a[0] and &a[0] point to the same place?

and:

Does a[0] == &a[0] evaluate to true?

It is not clear from your question which you mean. Your text asks “Is a[0] == &a[0]?” Since the “==” is not in code format, it is not clear whether you intended to exclude it.

The answer to the first question is yes (given that a[0] is automatically converted to an address), and the answer to the second question is not necessarily.

As other answers and comments have pointed out, a[0] and &a[0] are different things. a is an array of two arrays of three int. So a[0] is an array of three int, and, in most expressions, it is automatically converted to a pointer to its first element. So the result is a pointer to an int, effectively &a[0][0]. In contrast, &a[0] is the address of an array of three int.

So, these expressions point to two different objects, but the two objects start at the same location, so the pointers point to the same “place.” We can see this in:

(char *) a[0] == (char *) &a[0]  // Evaluates to true.

When we convert a pointer to a pointer to char, the result points to the first (lowest addressed) byte of the object. Since the two pointers point to the same place, this expression will evaluate to true.

However, when you evaluate a[0] == &a[0], there is a problem. To conform to the C standard, a comparison of pointers must compare pointers to compatible types. But int and array of three int are not compatible types. So this comparison is not strictly conforming C, although some compilers may allow it, likely with a warning message. We can instead evaluate:

a[0] == (int *) &a[0]  // Value is not specified.

By converting the pointer on the right to a pointer to int, we make the left and right sides have the same type, and we can compare them. However, the result of the comparison is not defined. This is because that, although the C standard allows us to convert a pointer to one type to a pointer to another type, it does not generally guarantee what the value that results from the conversion is, except that, if you convert it back to the original type, then it will compare equal to the original pointer. (Converting to a pointer to a character type is special; for those, the compiler does guarantee the result points to the first byte of the object.)

So, since we do not know what the value of (int *) &a[0] is, we do not know whether comparing it to a[0] will return true or false.

This might seem strange; if one address points to the same place as another address, why wouldn’t they compare equal? On some computers, there is more than one way of referring to the same place in memory. Addresses may actually be formed of comnbinations of parts, such as base addresses plus offsets. For example, the address (1000, 230), representing 1230, points to the same place as (1200, 30), also representing 1230. But clearly (1000, 230) is not the same as (1200, 30).

When you compare two pointers to the same type, the compiler automatically adjusts the representations of the addresses in whatever way it needs to to perform the comparison. But, when you convert a pointer to one type to a pointer to another (non-character) type, the change of types may prevent the compiler from having the information it needs to do this adjustment properly. So the C standard does not tell us what happens in this case.

Upvotes: 1

nabil.douss
nabil.douss

Reputation: 640

No they are not the same.

a[0] is an element of type int[3], while &a[0] is a pointer (of type int*[3]) to a[0].

But both of them points to the same address (the first element of a[0]), but are not the same.

Upvotes: 0

Sourav Ghosh
Sourav Ghosh

Reputation: 134346

I'm not sure what you meant to comapre using the == in your question, but let me tell you these, they are not the same.

  • Data type: Check the data type.

    • a[0] is the first element of the array of type int [3].
    • &a[0] is the pointer to the first element of the array of type int [3], so, it is essentially int (*) [3].
  • Usage: Now, based on the usage, in certain cases Note, an "array type", decays to a pointer to it's first element. Considering that case, a[0] and &a[0], both are equivalent to writing &(a[0][0]), so the pointer value will be same.

For better understanding of the difference, use both a[0] and &a[0] as the argument yo sizeof operator (where the decay does not happen) and print the value using %zu conversion specifier.

Typically, they will print

  • 12, which is (sizeof (int) * 3) and
  • 8, which is sizeof (int (*) [3])

    on a platform where size of an int is 4 and size of a pointer is 8.


[Note]:

Quoting C11, chapter §6.3.2.1

Except when it is the operand of the sizeof operator, the _Alignof operator, or the unary& operator, or is a string literal used to initialize an array, an expression that has type ‘‘array of type’’ is converted to an expression with type ‘‘pointer to type’’ that points to the initial element of the array object and is not an lvalue. [....]

Upvotes: 1

Some programmer dude
Some programmer dude

Reputation: 409196

First of all, the type of arrayNum[0] is Int[3] and the type of &arrayNum[0] is Int(*)[3] (I didn't change the OP's Int to the probable int).

Secondly, arrays can decay to a pointer to its first element, so arrayNum[0] can decay to &arrayNum[0][0] which is of type Int*.

Both those pointers, &arrayNum[0] and &arrayNum[0][0] will point to the same location, but their types are very different.

Upvotes: 3

Related Questions