Массив char * должен заканчиваться на '\ 0' или "\ 0"?
Допустим, у нас есть массив указателей char
char* array[] = { "abc", "def" };
Теперь, что нужно положить в конец?
char* array[] = { "abc", "def", '\0' };
или
char* array[] = { "abc", "def", "\0" };
Хотя, оба работают. Мы должны только поставить условие, чтобы проверить конец соответственно
как
array[ index ] != '\0';
или
array[ index ] != "\0";
Мой вопрос в том, какой из них лучше? Что используется большинством программистов?
Edit
Большинство ответов говорят, что NULL лучше, чем "\ 0" и "\ 0".
Но я всегда думал, что
NULL совпадает с '\ 0', который равен 0x0 или 0
Это неправильно?
Ответы
Ответ 1
Я бы закончил с NULL
. Зачем? Потому что вы не можете сделать ничего из этого:
array[index] == '\0'
array[index] == "\0"
Первый сравнивает char *
с a char
, который не то, что вы хотите. Вы должны были бы сделать это:
array[index][0] == '\0'
Второй даже не работает. Вы сравниваете char *
с a char *
, да, но это сравнение бессмысленно. Он проходит, если два указателя указывают на одну и ту же часть памяти. Вы не можете использовать ==
для сравнения двух строк, вам нужно использовать функцию strcmp()
, потому что C не имеет встроенной поддержки строк за пределами нескольких (и я имею в виду мало) синтаксических тонкостей. Принимая во внимание следующее:
array[index] == NULL
Хорошо работает и передает вашу точку.
Ответ 2
Согласно спецификации C99,
-
NULL
расширяется до константы нулевого указателя, которая не обязана быть, но обычно имеет тип void *
-
'\0'
- символьная константа; символьные константы имеют тип int
, поэтому он эквивалентен равному 0
-
"\0"
- строковый литерал с нулевым завершением и эквивалентен составному литералу (char [2]){ 0, 0 }
NULL
, '\0'
и 0
- все константы нулевого указателя, поэтому все они будут отображать нулевые указатели на преобразование, тогда как "\0"
дает ненулевой char *
(который следует рассматривать как const
как модификация undefined); поскольку этот указатель может быть различным для каждого вхождения литерала, он не может использоваться в качестве контрольного значения.
Хотя вы можете использовать любое целочисленное постоянное выражение значения 0
как константу нулевого указателя (например, '\0'
или sizeof foo - sizeof foo + (int)0.0
), вы должны использовать NULL
, чтобы ваши намерения были понятны.
Ответ 3
Из этих двух, первая является ошибкой типа: '\ 0' является символом, а не указателем. Компилятор все еще принимает его, потому что он может преобразовать его в указатель.
Второй "работает" только по совпадению. "\ 0" - строковый литерал из двух символов. Если они встречаются в нескольких местах исходного файла, компилятор может, но не обязательно, сделать их идентичными.
Таким образом, правильный способ записи первого -
char* array[] = { "abc", "def", NULL };
и вы проверите для array[index]==NULL
. Правильный способ проверки для второго
array[index][0]=='\0'
; вы также можете отбросить "\ 0" в строке (т.е. записать его как ""
), так как это уже будет содержать нулевой байт.
Ответ 4
Ну, технически '\0'
является символом, а "\0"
является строкой, поэтому, если вы проверяете нулевой символ окончания, первое верно. Однако, как отмечает Крис Лутц в своем ответе, ваше сравнение не будет работать в текущей форме.
Ответ 5
Прекращение массива символов с нулевым символом - это просто соглашение, которое специально для строк в C. Вы имеете дело с чем-то совершенно другим - массивом указателей на символы, поэтому он действительно не имеет никакого отношения к соглашение для строк C. Конечно, вы можете выбрать его с помощью нулевого указателя; возможно, это может быть ваша конвенция для массивов указателей. Есть и другие способы сделать это. Вы не можете спросить людей, как это "должно" работать, потому что вы принимаете какое-то соглашение, которого нет.
Ответ 6
Нулевое завершение - плохой дизайн, который лучше всего оставить в книгах по истории. По-прежнему существует инерция позади c-струн, поэтому ее там нельзя избежать. Но нет причин использовать его в примере OP.
Не используйте терминатор и используйте sizeof (array)/sizeof (array [0]), чтобы получить количество элементов.