Доступ к элементу массива с использованием поведения char undefined?

Так как неясно, какое поведение undefined, а что нет в C, мне интересно, является ли доступ к элементу массива с помощью char поведением undefined. Например:

char c = 'A';
int a[3000];
printf("%i\n", a[c]);

Я знаю, что на самом деле символы и ints являются взаимозаменяемыми, но все же я не уверен.

Ответы

Ответ 1

Синтаксически a[c] является допустимым выражением, если c является целым типом или может быть присвоено целочисленному типу.

Из стандарта C99:

6.5.2.1 Подстрока массива

1 Одно из выражений должно иметь тип '' указатель на тип объекта, другое выражение должно иметь целочисленный тип, а результат имеет тип типа '.

Если значение c. после повышения до int, находится в пределах массива, тогда во время выполнения не должно быть проблем.

Ответ 2

Доступ к элементу массива с помощью поведения char undefined?

Это не поведение undefined. Он работает как другой целочисленный тип. Но числовое значение a char может быть неожиданно отрицательным.


A char имеет тот же диапазон, что и signed char или unsigned char. Реализация определена.

Использование c в качестве индекса в порядке, если продвинутый индекс плюс указатель приводит к действительному адресу памяти. Подробно: A char будет увеличено до int или возможно unsigned.

Вероятно, следующая проблема имеет отрицательное значение c. В случае OP с кодировкой ASCII 'A' имеет значение 65, поэтому у него нет проблемы как 0 <= 65 < 3000. @Джойхим Пилеборг

char c = 'A';
int a[3000] = { 0 };
printf("%i\n", a[c]);  // OK other than a[] not initialize in OP code.

Ответ 3

Из всего, что я знаю, я бы сказал, что это не undefined, но довольно четко определено. Причина: A char может быть повышена до integer, что является допустимым способом индексирования массива (или лучше сказано: указатель, который массив распадается на это выражение). Индексация в основном такая же, как и добавление:

pointer + index // same as &(pointer[index]) or &(index[pointer])

И, цитируя http://en.cppreference.com/w/cpp/language/implicit_cast (в разделе "Числовые рекламные акции" ):

[..] Prvalues ​​малых интегральных типов (например, char) могут быть преобразованы в prvalues ​​более крупных интегральных типов (например, int). В частности, арифметические операторы не принимают типы, меньшие, чем int, в качестве аргументов, [..]

Компиляторы AFAIK выдадут предупреждение, хотя, как правило, вы не используете индекс char as, поэтому компилятор пытается обеспечить дополнительную сеть безопасности.

Ответ 4

В основном это будет работать, но будьте осторожны с символами, отличными от ASCII, со значением > 127

Если знак char подписан, он получит повышение до отрицательного целого числа, что приведет к доступу к памяти за пределами массива!

Это обычная ошибка в наивных реализациях, например. tolower()

Ответ 5

Это должно автоматически присваиваться int и перейти к этому элементу массива, поэтому поведение не undefined. Однако для этого никогда не было причин. Даже если вы начинаете с "(десятичное значение ASCII 32), вы не используете другие 32 значения перед ним.

Я думаю, вы, вероятно, пытаетесь создать очень основную хеш-таблицу. Это легко сделать с помощью структуры и нескольких функций; обычно бывает плохой практикой использовать что-либо, кроме целочисленного типа (даже если char можно отличить от int) в качестве индекса массива.