Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ array[index] vs index[array] [duplicate]

Tags:

c++

arrays

c

Possible Duplicate:
In C arrays why is this true? a[5] == 5[a]

Is the possibility of both array[index] and index[array] a compiler feature or a language feature. How is the second one possible?

like image 662
Babiker Avatar asked May 25 '09 07:05

Babiker


People also ask

What is the need of index in an array?

The index indicates the position of the element within the array (starting from 1) and is either a number or a field containing a number.

How to check if an array has duplicate values in c++?

Check if array contains duplicates using unique() function The unique() function return an iterator. If array doesn't contains duplicate then the returned iterator points to the end of the array, otherwise iterator points somewhere else in array. The Array contains duplicates. The Array contains duplicates.

Is pointer arithmetic faster than array indexing?

Pointer arithmetic is slightly faster (about %10) than array indexing.

Can you index an array in C?

Arrays in C are indexed starting at 0, as opposed to starting at 1. The first element of the array above is point[0]. The index to the last value in the array is the array size minus one.


3 Answers

The compiler will turn

index[array]

into

*(index + array)

With the normal syntax it would turn

array[index]

into

*(array + index)

and thus you see that both expressions evaluate to the same value. This holds for both C and C++.

like image 117
Martin Geisler Avatar answered Oct 16 '22 11:10

Martin Geisler


From the earliest days of C, the expression a[i] was simply the address of a[0] added to i (scaled up by the size of a[0]) and then de-referenced. In fact, all these were equivalent:

a[i]
i[a]
*(a+i)

====

The only thing I'd be concerned about is the actual de-referencing. Whilst they all produce the same address, de-referencing may be a concern if the types of a and i are different.

For example:

    int i = 4;
    long a[9];
    long x = a[i]; //get the long at memory location X.
    long x = i[a]; //get the int at memory location X?

I haven't actually tested that behavior but it's something you may want to watch out for. If it does change what gets de-referenced, it's likely to cause all sorts of problems with arrays of objects as well.

====

Update:

You can probably safely ignore the bit above between the ===== lines. I've tested it under Cygwin with a short and a long and it seems okay, so I guess my fears were unfounded, at least for the basic cases. I still have no idea what happens with more complicated ones because it's not something I'm ever likely to want to do.

like image 40
paxdiablo Avatar answered Oct 16 '22 10:10

paxdiablo


As Matthew Wilson discusses in Imperfect C++, this can be used to enforce type safety in C++, by preventing use of DIMENSION_OF()-like macros with instances of types that define the subscript operator, as in:

#define DIMENSION_OF_UNSAFE(x)  (sizeof(x) / sizeof((x)[0]))

#define DIMENSION_OF_SAFER(x)  (sizeof(x) / sizeof(0[(x)]))

int ints[4];

DIMENSION_OF_UNSAFE(ints); // 4
DIMENSION_OF_SAFER(ints); // 4

std::vector v(4);

DIMENSION_OF_UNSAFE(v); // gives impl-defined value; v likely wrong
DIMENSION_OF_SAFER(v); // does not compile

There's more to this, for dealing with pointers, but that requires some additional template smarts. Check out the implementation of STLSOFT_NUM_ELEMENTS() in the STLSoft libraries, and read about it all in chapter 14 of Imperfect C++.

edit: some of the commenters suggest that the implementation does not reject pointers. It does (as well as user-defined types), as illustrated by the following program. You can verify this by uncommented lines 16 and 18. (I just did this on Mac/GCC4, and it rejects both forms).

#include <stlsoft/stlsoft.h>
#include <vector>
#include <stdio.h>

int main()
{
    int     ar[1];
    int*    p = ar;
    std::vector<int>        v(1);

    printf("ar: %lu\n", STLSOFT_NUM_ELEMENTS(ar));

//  printf("p: %lu\n", STLSOFT_NUM_ELEMENTS(p));

//  printf("v: %lu\n", STLSOFT_NUM_ELEMENTS(v));

    return 0;
}
like image 5
dcw Avatar answered Oct 16 '22 10:10

dcw