Если строковые массивы заканчиваются нулем в C, почему массивы других типов данных не заканчиваются нулем? - PullRequest
2 голосов
/ 13 июня 2019

Строки или массивы символов в C должны заканчиваться нулем, чтобы знать, где они заканчиваются. Почему это же правило не применяется к массивам других типов? например. Как компьютер узнает, где заканчивается массив целых чисел? Есть ли разница в том, как массивы целых / плавающих / двойных представляются в памяти?

Ответы [ 4 ]

2 голосов
/ 14 июня 2019

Массивы символов не обязательно должны заканчиваться нулями.

char foo[3]="foo"; //not nul-terminated
char bar[]={'b','a','r'}; //not nul-terminated

Просто строковые литералы являются массивами с нулевым терминалом, и C позволяет действительно легко создавать массивы с нулевым символом в конце, используястроковые литералы в качестве инициализаторов:

 char baz[]="baz"; //nul-terminated because "baz" is

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

Но ничто в Си не навязывает вам это предпочтение.

1 голос
/ 14 июня 2019

Краткий ответ: потому что так определяется язык Си.

Более длинный ответ: строки C сами по себе ничего особенного. Это блок памяти, который содержит байты, как и любой другой блок. Но, определив соглашение о завершении строки на 0, все функции могут договориться о способах обработки строк.

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

Что касается того, почему он не используется с другими типами, то иногда это так. И причина та же: она была согласована как соглашение и так же, как строки. Мы не знаем, сколько существует значений, поэтому в конце мы имеем дозорное значение. Это может быть ноль, 0 или другое значение. Но мы также не можем сделать это и предоставить количество элементов отдельно.

Также часто невозможно и / или не нужно использовать значение часового, например, если нам нужен полный тип данных или мы знаем размер данных. Например, если у нас есть изображение RGB, как мы определим конечное значение? Нам нужны все значения, которые байты могут определять цвета, чтобы у нас не было часового. Нам также не нужен, так как мы знаем размер изображения.

Что касается компьютера, он ничего не знает о данных. Он может обрабатывать только байты и слова и все, что он создан для обработки. Строки гораздо более высокого уровня и обрабатываются полностью в библиотеке используемого языка. Процессор просто перемещает данные в зависимости от того, что вы говорите. И, например, BIOS компьютера использует $ как символ-терминатор при печати строк, а не 0.

1 голос
/ 13 июня 2019

Строка в C - это последовательность char с нулевым окончанием. Это особый случай массива char.

Вы можете иметь массив char, который не завершен нулем. Например:

char x[] = { 'a', 'b', 'c' };

Массивы в целом представлены в виде непрерывной последовательности базового типа в памяти. Сам язык не отслеживает, насколько большой массив, вы должны делать это самостоятельно.

0 голосов
/ 14 июня 2019

Вы обычно передаете длину массива вместе с указателем.Ничто не «знает» длину чего-либо.

Память - это память.Массив байтов может содержать 0x42 0x41 0x44 0x00, что является строкой для "BAD", но это может быть также целое число, представляющее "1145127936", или число с плавающей точкой, представляющее "773.0625"

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