Зачем использовать форму const char * для строки

#c

#c

Вопрос:

Используйте следующие две формы создания строки:

 const char* pt1 = "Hello";
      char* pt2 = "Goodbye";
 

Какая польза const в приведенном выше? В моем понимании, выполнение:

 ptr = "Adios";
 

Будет работать для обоих, поскольку это изменяет адрес указателя, но попытка изменить букву в строке приведет к сбою для обоих:

 const char* pt1 = "Hello";
 

ошибка компилятора: назначение местоположения только для чтения

 char* pt2 = "Goodbye";
 

ошибка времени выполнения: ошибка seg, попытка изменить .rodata

Поскольку они выдают один и тот же результат, т.Е. Ошибку, Есть ли какое-либо преимущество в использовании const при определении строки?

Комментарии:

1. Since they produce the same output compiler error: assignment of read-only location определенно отличается от runtime error: seg fault, trying to change .rodata .

2. Но когда вы хотели бы потерпеть неудачу? Когда вы компилируете свою программу или когда ваш клиент купил вашу программу, и вы отправляете свою программу, и в ней обнаруживаются ошибки, поэтому вам нужно вернуть деньги? Существует определенное различие между compiler error и runtime error — первое легко обнаружить и исправить. Другая ошибка является ошибкой программы и может иметь катастрофические последствия.

3. @samuelbrody1249 вы должны добавить к имени другого человека знак @, чтобы уведомить его.

4. @KamilCuk Я вижу, так что в принципе все, что вы можете сделать, чтобы вскипятить ошибку, чтобы ее перехватил компилятор, предпочтительнее, верно?

5. Да — статический анализ кода очень предпочтительнее ошибок во время выполнения.

Ответ №1:

Определение указателей, которые указывают на строковые константы (также известные как строковые литералы), as const char * позволяет компилятору обнаруживать неправильный доступ, если где-то еще в коде вы пытаетесь изменить то, что pt1 указывает на as , в *pt1 = 'A'; то время как у вас просто было бы неопределенное поведение во время выполнения, если pt1 бы был тип char * , вызывающий сбой на некоторых архитектурах и менее очевидный, но потенциальноболее разрушительные побочные эффекты для других.

Чтобы расширить эту тему, иногда возникает путаница в отношении значения const определений указателей:

const char *pt1 = "Hello"; определяет изменяемый указатель pt1 , который указывает на массив char , который не может быть изменен с его помощью. Поскольку "Hello" это строковая константа, это правильный тип для pt1 . pt1 может быть изменен, чтобы указывать на другую строку или char , изменяемый или нет, или быть установлен в NULL .

char *pt2 = "Hello"; определяет изменяемый указатель pt2 , который указывает на массив char , который может быть изменен с его помощью. Стандарт C допускает это, несмотря на постоянство "Hello" для совместимости с историческим кодом. gcc и clang могут отключить это поведение с -Wwrite-strings помощью опции командной строки. Я настоятельно рекомендую использовать это и многие другие предупреждения, чтобы избежать распространенных ошибок.

const char * const pt3 = "Hello"; определяет постоянный указатель pt3 , который указывает на массив char , который не может быть изменен с его помощью. pt3 не может быть изменен, чтобы указывать на другую строку или даже быть установлен на NULL .

char * const pt4 = "Hello"; определяет постоянный указатель pt4 , который указывает на массив char , который может быть изменен с его помощью. pt4 невозможно изменить после инициализации.

char и const может быть размещен в любом порядке, но const * имеет большое значение, находится ли он до или после.

Ответ №2:

Для чего используется const в приведенном выше?

 const char* pt1 = "Hello";
 

Просто означает, что вы не можете изменить данные, на которые pt1 указывают.

Оба

 const char* ptr1 = "Hello";
char* pt2 = "Goodbye";
 

создайте статическую память для строкового литерала. Я предлагаю вам прочитать это.

Таким образом, преимущество заключается в том, что сначала вы всегда будете получать ошибку времени компиляции, а во-вторых, это может зависеть от компилятора. Некоторые компиляторы делают это автоматически. смотрите страницу, на которую я ссылался.

Ответ №3:

Зачем использовать const char* форму для строки

Использовать const char *ptr1 , когда строка, на которую ссылается ссылка, не должна изменяться, и позволяет компилятору оптимизировать на основе этого.

Это всегда имеет место при назначении с помощью строковых литералов.

Используйте char *ptr2 , когда строка, на которую ссылается ссылка, может быть изменена.

Опасность char* pt2 = "Goodbye"; заключается в том, что более поздний код может попытаться изменить данные, на которые ссылается pt2 , которые в настоящее время указывают на строковый литерал.

Ответ №4:

Зачем использовать форму const char * для строки

Чтобы уведомить себя и других разработчиков о том, что память, на которую указывает указатель, не может быть изменена. В этом контексте const ключевое слово в основном предназначено для программиста, чтобы уведомить программиста о том, что данные, на которые указывает указатель, являются const .

в принципе, все, что вы можете сделать, чтобы вскипятить ошибку, чтобы ее перехватил компилятор, предпочтительнее, верно?

ДА. Это причина, по которой разработчики стремятся изобрести лучшие инструменты для статического анализа кода. Существует множество инструментов для статического анализа кода, и недавно компилятор GNU gcc 11 поставляется с внутренним статическим анализом кода. Это также причина, по которой такие языки, как Rust изобретены и так популярны. Все инструменты пытаются выдать как можно больше ошибок, которые можно обнаружить «статически» — во время компиляции.

У Gcc также есть предупреждение с -Wwrite-strings предупреждением о char *str = "str" том, что подобный код присваивает const-литерал неконстантному указателю.

Комментарии:

1. «Чтобы уведомить себя и других разработчиков», я бы сказал, себя, других разработчиков и компилятора. 1 для общего ответа, хотя!!!

Ответ №5:

Как указал Камильчук, изменение const char* pt1 = "Hello"; выдает ошибку уже во время компиляции, когда вы можете просто исправить код, перекомпилировать, и все в порядке. Изменение char* pt1 = "Hello"; выдает ошибку во время выполнения, и вы не хотите, чтобы все ваши 1 миллион пользователей повторно загружали и переустанавливали вашу программу (для этого вам пришлось бы сначала купить лучшее подключение к Интернету). Итак, вам определенно следует использовать const char* .

Комментарии:

1. Ваше объяснение несколько сбивает с толку: определение pt1 того или иного способа не вызывает ошибки, но определение его как const char* pt1 = "Hello"; позволит компилятору обнаружить неправильный доступ, если где-то еще в коде вы попытаетесь изменить what pt1 указывает на as в *pt1 = 'A';

2. @Rob я не запрашивал разъяснений у OP и не критиковал его; это дает ответ на этот вопрос!