With arrays, why is it the case that a[5] == 5[a]?

2018-12-30 23:04发布

As Joel points out in Stack Overflow podcast #34, in C Programming Language (aka: K & R), there is mention of this property of arrays in C: a[5] == 5[a]

Joel says that it's because of pointer arithmetic but I still don't understand. Why does a[5] == 5[a]?

17条回答
栀子花@的思念
2楼-- · 2018-12-30 23:34

I just find out this ugly syntax could be "useful", or at least very fun to play with when you want to deal with an array of indexes which refer to positions into the same array. It can replace nested square brackets and make the code more readable !

int a[] = { 2 , 3 , 3 , 2 , 4 };
int s = sizeof a / sizeof *a;  //  s == 5

for(int i = 0 ; i < s ; ++i) {  

           cout << a[a[a[i]]] << endl;
           // ... is equivalent to ... 
           cout << i[a][a][a] << endl;  // but I prefer this one, it's easier to increase the level of indirection (without loop)

}

Of course, I'm quite sure that there is no use case for that in real code, but I found it interesting anyway :)

查看更多
君临天下
3楼-- · 2018-12-30 23:34

I know the question is answered, but I couldn't resist sharing this explanation.

I remember Principles of Compiler design, Let's assume a is an int array and size of int is 2 bytes, & Base address for a is 1000.

How a[5] will work ->

Base Address of your Array a + (5*size of(data type for array a))
i.e. 1000 + (5*2) = 1010

So,

Similarly when the c code is broken down into 3-address code, 5[a] will become ->

Base Address of your Array a + (size of(data type for array a)*5)
i.e. 1000 + (2*5) = 1010 

So basically both the statements are pointing to the same location in memory and hence, a[5] = 5[a].

This explanation is also the reason why negative indexes in arrays work in C.

i.e. if I access a[-5] it will give me

Base Address of your Array a + (-5 * size of(data type for array a))
i.e. 1000 + (-5*2) = 990

It will return me object at location 990.

查看更多
千与千寻千般痛.
4楼-- · 2018-12-30 23:35

Because array access is defined in terms of pointers. a[i] is defined to mean *(a + i), which is commutative.

查看更多
梦该遗忘
5楼-- · 2018-12-30 23:36

Nice question/answers.

Just want to point out that C pointers and arrays are not the same, although in this case the difference is not essential.

Consider the following declarations:

int a[10];
int* p = a;

In a.out, the symbol a is at an address that's the beginning of the array, and symbol p is at an address where a pointer is stored, and the value of the pointer at that memory location is the beginning of the array.

查看更多
初与友歌
6楼-- · 2018-12-30 23:36

Not an answer, but just some food for thought. If class is having overloaded index/subscript operator, the expression 0[x] will not work:

class Sub
{
public:
    int operator [](size_t nIndex)
    {
        return 0;
    }   
};

int main()
{
    Sub s;
    s[0];
    0[s]; // ERROR 
}

Since we dont have access to int class, this cannot be done:

class int
{
   int operator[](const Sub&);
};
查看更多
残风、尘缘若梦
7楼-- · 2018-12-30 23:39

pointer types

1) pointer to data

int *ptr;

2) const pointer to data

int const *ptr;

3) const pointer to const data

int const *const ptr;

and the arrays are type of (2) from our list
When you define an array at a time one address is initialize in that pointer
As we know that we can't change or modify const value in our program cause it's throws an ERROR at compile time

The major difference I found is...

We can re-initialize the pointer by an address but not the same case with an array.

======
and back to your question...
a[5] is nothing but *(a + 5)
you can understand easily by
a - containing address (people call it as base address) just like an (2) type of pointer in our list
[] - that operator can be replaceable with pointer * .

so finally...

a[5] == *(a +5) == *(5 + a) == 5[a] 
查看更多
登录 后发表回答