Массив 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]), чтобы получить количество элементов.