char *name
Вы можете изменить символ, на который указывает name
, а также символ, на который он указывает.
const char* name
Вы можете изменить символ, на который указывает name
, но вы не можете изменить символ, на который он указывает. коррекция: Вы можете изменить указатель, но не символ, на который указывает name
(https://msdn.microsoft.com/en-us/library/vstudio/whkd4k6a(v=vs.100).aspx,см. «Примеры»).В этом случае спецификатор const
применяется к char
, а не к звездочке.
Согласно странице MSDN и http://en.cppreference.com/w/cpp/language/declarations, const
до *
является частьюпоследовательность спецификатора decl, а const
после *
является частью декларатора.За последовательностью спецификатора объявления могут следовать несколько объявлений, поэтому const char * c1, c2
объявляет c1
как const char *
и c2
как const char
.
РЕДАКТИРОВАТЬ:
Судя по комментариям, ваш вопрос, похоже, касается разницы между двумя объявлениями, когда указатель указывает на строковый литерал.
В этом случае вы не должны изменять символ, на который указывает name
, так как это может привести к неопределенному поведению .Строковые литералы могут быть размещены в областях памяти, доступных только для чтения (реализация определяется), и пользовательская программа не должна изменять их в любом случае.Любая попытка сделать это приводит к неопределенному поведению.
Таким образом, единственное отличие в этом случае (при использовании строковых литералов) заключается в том, что второе объявление дает вам небольшое преимущество.Компиляторы обычно выдают предупреждение в случае, если вы пытаетесь изменить строковый литерал во втором случае.
Пример интерактивного примера:
#include <string.h>
int main()
{
char *str1 = "string Literal";
const char *str2 = "string Literal";
char source[] = "Sample string";
strcpy(str1,source); //No warning or error, just Undefined Behavior
strcpy(str2,source); //Compiler issues a warning
return 0;
}
Вывод:
cc1: предупреждения рассматриваются как ошибки
prog.c: в функции 'main':
prog.c: 9: error:передача аргумента 1 в 'strcpy' отбрасывает квалификаторы из целевого типа указателя
Обратите внимание, что компилятор предупреждает о втором случае, но не о первом.