Указатель и массивы разные.Определение строковых констант как указателей или массивов соответствует различным целям.
Когда вы определяете глобальную строковую константу, которая не подлежит изменению, я бы рекомендовал сделать ее константным массивом:
const char product_name[] = "The program version 3";
Определение его как const char *product_name = "The program version 3";
фактически определяет 2 объекта: саму строковую константу, которая будет находиться в сегменте константы, и указатель, который можно изменить, чтобы он указывал на другую строку или установил на NULL
.
И наоборотопределение строковой константы как локальной переменной лучше сделать в виде локальной переменной-указателя типа const char *
, инициализированной адресом строковой константы:
int main() {
const char *s1 = "world";
printf("Hello %s\n", s1);
return 0;
}
Если вы определите эту переменную как массивв зависимости от компилятора и использования внутри функции код освободит пространство для массива в стеке и инициализирует его, скопировав в него строковую константу, что является более дорогостоящей операцией для длинных строк.
Обратите также внимание, чтоconst char const *s3 = "baz";
является избыточной формой const char *s3 = "baz";
.Он отличается от const char * const s3 = "baz";
, который определяет постоянный указатель на постоянный массив символов.
Наконец, строковые константы являются неизменяемыми и поэтому должны иметь тип const char []
.Стандарт C специально позволяет программистам сохранять свои адреса в неконстантных указателях, как в char *s2 = "hello";
, чтобы избежать выдачи предупреждений для унаследованного кода.В новом коде настоятельно рекомендуется всегда использовать указатели const char *
для манипулирования строковыми константами.Это может заставить вас объявить аргументы функции как const char *
, когда функция не изменяет содержимое строки.Этот процесс известен как constification и позволяет избежать незначительных ошибок.
Обратите внимание, что некоторые функции нарушают это const
распространение: strchr()
не изменяет полученную строку, объявленную как const char *
,но возвращает char *
.Таким образом, можно сохранить указатель на строковую константу в простом указателе char *
следующим образом:
char *p = strchr("Hello World\n", 'H');
Эта проблема решается в C ++ с помощью перегрузки.Программисты C должны иметь дело с этим как с недостатком.Еще более раздражающая ситуация - strtol()
, когда передается адрес char *
и требуется преобразование для сохранения правильной константности.