Массив C++ [индекс] по сравнению с индексом [массив] [дубликат]

Этот ответ содержит ошибки. Как уже отмечалось, не существует решения этой проблемы, которое гарантированно будет работать при внедрении новых платформ, кроме использования метода «10-элементный массив».


Ответ от solidsun работал хорошо, пока я не пошел на компиляцию с 64-битной архитектурой. Это вызвало ошибку:

EXC_BAD_ADDRESS type EXC_I386_GPFLT

Решением было использование немного другого подхода для передачи списка аргументов в метод:

+ (id)stringWithFormat:(NSString *)format array:(NSArray*) arguments;
{
     __unsafe_unretained id  * argList = (__unsafe_unretained id  *) calloc(1UL, sizeof(id) * arguments.count);
    for (NSInteger i = 0; i < arguments.count; i++) {
        argList[i] = arguments[i];
    }

    NSString* result = [[NSString alloc] initWithFormat:format, *argList] ;//  arguments:(void *) argList];
    free (argList);
    return result;
}

Это работает только для массивов с одним элементом

12
задан Community 23 May 2017 в 11:33
поделиться

4 ответа

Компилятор превратит

index[array]

в

*(index + array)

. При обычном синтаксисе он превратит

array[index]

в

*(array + index)

, и вы увидите, что оба выражения дают одно и то же значение. Это справедливо как для C, так и для C ++.

29
ответ дан 2 December 2019 в 03:43
поделиться

С самых ранних дней C выражение a [i] было просто адресом [0], добавленным к i (увеличенное в масштабе размером a [0]), а затем ссылка на него отменяется. Фактически, все они были эквивалентны:

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

====

Единственное, что меня беспокоит, - это фактическое разыменование. Хотя все они выдают один и тот же адрес , разыменование может быть проблемой, если типы a и i различны.

Например:

    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?

Я на самом деле не проверял такое поведение, но вы можете остерегаться этого. Если он действительно изменит то, что лишается ссылки, это, вероятно, вызовет всевозможные проблемы с массивами объектов.

====

Обновление:

Вы, вероятно, можете спокойно игнорировать бит выше между ===== строк. Я тестировал его под Cygwin с коротким и длинным, и мне кажется, все в порядке, поэтому я думаю, что мои опасения были необоснованными, по крайней мере, для основных случаев. Я до сих пор не знаю, что происходит с более сложными, потому что я вряд ли когда-либо захочу этого делать.

6
ответ дан 2 December 2019 в 03:43
поделиться

In C and C++ (with array being a pointer or array) it is a language feature: pointer arithmetic. The operation a[b] where either a or b is a pointer is converted into pointer arithmetic: *(a + b). With addition being symetrical, reordering does not change meaning.

Now, there are differences for non-pointers. In fact given a type A with overloaded operator[], then a[4] is a valid method call (will call A::operator ) but the opposite will not even compile.

0
ответ дан 2 December 2019 в 03:43
поделиться

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;
}
5
ответ дан 2 December 2019 в 03:43
поделиться