Роль const для массива строковых литералов C - PullRequest
0 голосов
/ 18 мая 2018

Я хотел бы проверить роли двух спецификаторов 'const' в следующей инициализации массива строковых литералов C:

const char* const myArray[] = { "one", "two", "three" };

Я прочитал предыдущие вопросы по SO и понял, что second const означает, что элементы массива не могут быть изменены, что я интерпретирую как адреса, содержащиеся в указателях myArray [0] и т. Д., Не должны изменяться.Таким образом, при наличии этого «const»

myArray[0] = "uno"; 

не компилируется («ошибка: назначение местоположения только для чтения« myArray [0] »)), но при его удалении назначение работает нормально.

Однако я не могу найти подобный пример, иллюстрирующий роль first 'const' выше, что должно означать, что литералы myArray сами не могут быть изменены (но как они могли измениться в любом случае?).Я пробовал что-то вроде этого:

myArray[0][0] = 'u'; 

, и когда присутствует первый 'const', я получаю ошибку компиляции ("ошибка: назначение местоположения только для чтения" * (myArray [0]) '")но без этого я получаю «сбой запуска» с NetBeans и MinGW.

Может кто-нибудь представить лучший пример для роли первого «const» выше?Большое спасибо.

1 Ответ

0 голосов
/ 18 мая 2018

Ваше объявление const char* const myArray[] расширяется до -

массив константного указателя на постоянные символы

Это означает, что это массив указателей, которые являются постоянными,поэтому не может быть изменено после инициализации.И символы, на которые он указывает, также являются постоянными, то есть вы можете разыменовать указатель, чтобы только читать символы, но не могли их перезаписать.

Этот массив инициализируется в массив, содержащий три строки "one", "two" и "three".

Таким образом, такие операции, как

myArray[i] = ...;
*myArray[i] = ...;

, не будут выполнены, но такие операции, как -

otherArray = myArray[i];
char t = *myArray[i];

, будут в порядке.

Это также причина, по которой код, подобный myArray[0] = "uno", не компилируется.

Вы пытаетесь назначить новую строку для myArray[0], но она объявлена ​​как const(const, который следует после *, вызывает это).

Теперь перейдем к вашему вопросу о myArray[0][0] = 'u';.Даже если вы удалите первые const, строковые литералы будут по умолчанию const.Вы не можете изменить символы, которые они содержат.Компилятор не жалуется на присваивание, потому что он не знает, что myArray[0] указывает на постоянную строку.

Это проблема со стандартом C, что строковые литералы имеют тип char*, а не const char*.Это не может быть изменено сейчас, потому что много устаревшего кода, который использует это, сломается.

...