Если я объявляю массив символов, должен ли я также считать нулевой символ? - PullRequest
0 голосов
/ 09 февраля 2019

Например:

char array[][5] = {"game", "house"};

Является ли house подходящим для массива или мне нужно добавить нулевой символ, поэтому я должен объявить так:

char array[][6] = {"game", "house"};

Ответы [ 4 ]

0 голосов
/ 09 февраля 2019
char array[][5] = {"game", "house"};

Подходит house для массива

Да.«Дом» подходит для инициализации массива array[1].array[1], однако, не является строкой , поскольку в нем отсутствует нулевой символ .array[0] - это строка array[1], и array[0] являются массивами char.


try char array[][5] = { "house", "game"}
это печатает "игру в дом"

Этопроблема с print("%s", array[0]);."%s" ожидает совпадения указателя на строку .Здесь array[0] не является строкой .

Чтобы напечатать массив символов, который может / не может быть строкой , используйте точность .Печать остановится, когда будет достигнута точность или при обнаружении нулевого символа .

char array[][5] = { "house", "game"};
print("<%.*s>\n", 5, array[0]);
print("<%.*s>\n", 5, array[1]);

Выход

<house>
<game>
0 голосов
/ 09 февраля 2019

Это зависит от того, что вы собираетесь делать со строками.

Определение

char array[][5] = {"game", "house"};

инициализирует array с размерами 2 и 5.array[0] будет инициализирован с элементами 'g', 'a', 'm', 'e', '\0' и array[1] как 'h', 'o', 'u', 's', 'e'.Обратите внимание на отсутствие завершающего '\0' на array[1].

То, что происходит затем, зависит от того, что ваш код впоследствии сделает с массивом.Например,

for (i = 0; i < 2; ++i)
{
   for (j = 0; j < 5, ++j)
   {
       if (array[i][j] != '\0')
           printf("%c", array[i][j]);
       else
           j = 5;    /*   terminate the inner loop */
   }       
   printf("\n");
}

с радостью напечатает две строки с game и house до stdout, поскольку циклы специально ограничивают себя, чтобы не получить доступ к элементу массива вне границ.

Однако

for (i = 0; i < 2; ++i)
{
   printf("%s\n", array[i]);
}

будет иметь неопределенное поведение, так как формат %s будет печатать каждый символ array[i] до тех пор, пока не будет найден завершающий '\0'.Поскольку array[1] инициализируется без завершения '\0', printf() обычно будет проходить за концом массива, т.е. проходить через любую память, расположенную сразу после конца array, и печатать любой мусор, который найдет добывает найти персонажа со значением '\0'.Если в памяти нет такого символа, доступного для программы, то программа может просто продолжать печатать символы мусора и затем аварийно завершать работу (например, если операционная система хоста обнаруживает, что программа обращается к памяти, она не должна, а затем принудительно завершает программу).

Общее правило: если вы используете какие-либо функции, которые предполагают наличие завершающего '\0' (printf() с форматом %s, strcat(), strcmp() и т. Д. И т. Д.), То ононеобходимо убедиться, что терминатор присутствует.Это означает, что в массиве достаточно элементов И инициализация одного из этих элементов '\0'.

Если вместо этого array инициализировать как

char array[][6] = {"game", "house"};

, тогда оба array[0] и array[1] иметь требуемый терминатор.

0 голосов
/ 09 февраля 2019

Просто замечание: молчаливое употребление терминального символа NULL строковых литералов - это особенность только Си.В C ++ запрещено предоставлять строки инициализации, которые больше, чем массив для инициализации.

0 голосов
/ 09 февраля 2019

Если вы будете использовать массив как строку , он должен включать завершающий нулевой символ.Завершающий нулевой символ является частью массива и должен быть включен в его размер.

Многие стандартные подпрограммы библиотеки C принимают аргументы, которые являются строками , которые являются массивами символов, оканчивающихся нанулевой символ.

Также возможно использовать массив символов для ваших собственных целей, не передавая его в стандартную библиотечную функцию, для которой требуется строка.Если вы будете использовать этот массив, вам не нужно включать завершающий нулевой символ.

Когда вы инициализируете такой массив строковыми литералами, вам не нужно включать пробел для завершающего нулевого символа.в размере массива.Завершающий нулевой символ в строковом литерале будет использоваться для инициализации элемента массива, только если есть место для него.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...