Доступ к элементу массива с использованием поведения 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) в качестве индекса массива.