Хотя эти два вида похожи и часто используются взаимозаменяемо, они означают разные вещи.Первая строка:
char a[] = "string literal";
... создает массив, достаточно большой для размещения строкового литерала, включая его терминатор NUL.Он инициализирует этот массив указанным строковым литералом.Одним из преимуществ этой версии является то, что массив может быть изменен позднее.Кроме того, размер массива известен даже во время компиляции, поэтому вы можете использовать оператор sizeof
для определения его размера.Например:
printf("%u\n",unsigned(sizeof(a))); // Will display 15, which is the array's size
// including the NUL terminator
Вторая строка:
char *p = "string literal";
... просто устанавливает указатель, указывающий на строковый литерал.Это быстрее, чем в первой версии, но у вас есть недостаток, заключающийся в том, что литерал не следует изменять, поскольку он может находиться на странице, помеченной как доступная только для чтения.У вас также есть недостаток, заключающийся в том, что для определения длины строки вам потребуется использовать функцию strlen()
, поскольку оператор sizeof
просто даст вам размер переменной-указателя.Например:
printf("%u\n",unsigned(sizeof(p))); // Will likely display 4 or 8, depending on
// whether this is a 32-bit or 64-bit build
printf("%u\n",unsigned(strlen(p))); // Will display the correct length of 14, not
// including the NUL terminator
Что лучше, зависит от того, что вы будете делать с этими переменными.Если вам не нужно вносить какие-либо изменения в строку, используйте более позднюю версию, но do измените char *
на const char *
, чтобы случайно не попытаться внести изменения в символыуказал на.Если вы намереваетесь изменить данные, используйте прежнюю версию на основе массива, которая позволяет вносить изменения в массив после инициализации.