Why does C array[6] equal 6[array]?

Asked

Viewed 523 times

20

Note: Question I saw in ONLY in English, but I found it interesting to put here (because we still don’t have many questions of C):

Because in the C language, this code prints "true"?

#include <stdio.h>

int main(void) {
    int reais[10];
    for(int i=0; i<10; ++i) reais[i] = i;
    int num = reais[6];
    int num2 = 6[reais];
    if(num == num2) printf("verdadeiro"); else printf("falso");
    return 0;
}

Note: I compiled this with C99, it DOES NOT COMPILE on C89 (because it cannot declare variable inside for() )

Anyone who wants to can copy and paste it into ideone. to see compile and rotate.

  • Cool. If it is very similar to the original, it would be good to put a link there to give credit.

  • An observation regarding the declaration of variables within the for(). In ANSI-C, variables can only be declared after "{" (braces) keys. In this case its scope is limited in the area where it was declared.

3 answers

20


Referencing the C standard:

6.5.2.1 Subscripting array

Constraints
One of the Expressions Shall have type "Pointer to complete Object type", the other Expression Shall have integer type, and the result has type "type".

Semantics
A postfix Expression Followed by an Expression in square Brackets [] is a subscripted Designation of an element of an array Object. The Definition of the subscript Operator [] is that E1[E2] is identical to (*((E1)+(E2))). Because of the Conversion Rules that apply to the Binary + Operator, if E1 is an array Object (equivalently, a Pointer to the initial element of an array Object) and E2 is an integer, E1[E2] designates the E2-th element of E1 (Counting from zero).

What matters is that when writing a[b], one of the values must be a pointer (or an array that decays to a pointer) and another must be an integral type. No restriction is specified on what should be what. The second point is that a[b] is equivalent to *(a+b). So we have:

a[b] = *(a+b) = *(b+a) = b[a]

The same can also be applied to literal strings, since they are const char[]:

char M = 4["Ola Mundo"];

Although this syntax is perfectly valid and legal, it is not good practice to access arrays by reversing the operands like this. The reading becomes quite unintuitive and there are no advantages.

  • Oxe, sensational response, better than in English. I didn’t imagine using char like that! It’s even a cool syntax :P

  • +1 for const char[]

  • 1

    +1 by 'intervening' instead of reversing

  • What is the 4 in char M = 4["Hello World"]; ?

9

When you define an array in C the operator [] defines the following:

reais[10] == *(reais + 10)

Soon reais[10] will be *(reais + 10) and 10[reais] will be *(10 + reais)

reais is a memory address, already reais[10] is the memory address + 10 positions in front of it. That’s how an array works it stores a pointer with the name + positions. And in basic mathematics we know that:

reais + 10 = 10 + reais

Source: Stackoverflow.com

3

Well... The first thing we have to have and mind here is that a vector, nothing else is a pointer to a certain memory region.

When the code line, int reais[10], is executed, 10 integers are allocated and the address of the first item is stored, only.

When you access a certain vector position, reais[6] for example, what really happens is that the program takes the address of the pointer, that is, of the first value (element) and sums it with the offset you passed times the size of the data. That is, the memory address effectively accessed is reais + 6*tamanho de um inteiro (multiplication by the size of the data is implicitly done, according to the type of the defined vector), where real is the address of the first element of the vector. In other words, what happens is: *(reais + 6). Note that the dereferencing operator is used.

That being said, when you use the notation 6[reais], what happens is exactly the same as described above. Only now you change the order of the sum between the address and the offset, ie, *(6 + reais).

As the addition is a commutative operation, the result is the same and so we access the same memory address. Soon, reais[6] == 6[reais].

This is because [] is an operator (so much so that in C++ you can overload it).

Browser other questions tagged

You are not signed in. Login or sign up in order to post.