Why in the C language array [6] equals 6 [array]?

20

Note: Question I saw in the SO in English , but I found it interesting to post here (because we do not have many C questions yet):

Because in C language, does this code print "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 COMPILATE in C89 (because it can not declare variable within the for ())

You can copy and paste this into ideone.com to see compile and run.

    
asked by anonymous 29.01.2014 / 16:11

3 answers

20

Referencing the C standard:

  

6.5.2.1 Array subscripting

     

Constraints
  One of the expressions shall have type "pointer to complete 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).

The relevant thing 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 a good practice to access arrays by reversing the operands as such. The reading is quite non-intuitive and there are no advantages.

    
29.01.2014 / 16:26
8

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, since reais[10] is the memory address + 10 positions in front of it. This is how a vector works it stores a pointer with the name + positions. And in basic math we know that:

reais + 10 = 10 + reais

Source: Stackoverflow.com

    
29.01.2014 / 16:22
3

Well ... The first thing we have to have and mind here is that a vector is nothing more than a pointer to a particular region of memory.

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

When you access a certain position of the vector, reais[6] for example, what actually happens is that the program takes the address of the pointer, that is, the first value (element) and sums with the offset that you passed times the size of the die. That is, the memory address actually accessed is reais + 6*tamanho de um inteiro (multiplication by data size is done implicitly, 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) . Notice that the dereference operator is used.

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

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

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

    
29.01.2014 / 16:30