Подтвердить что ты не робот

Почему строки в C должны быть пустыми?

Просто интересно, почему это так. Я очень хочу узнать больше о языках низкого уровня, и я только в основах C, и это уже меня пугает.

Используются ли языки, такие как PHP, автоматически нулевые строки, когда они интерпретируются и/или анализируются?

4b9b3361

Ответ 1

Из Джоэл отличная статья по теме:

Помните, как работают строки в C: они состоят из группы байтов, за которой следует нулевой символ, который имеет значение 0. Это имеет два очевидных значения:

Невозможно узнать, где заканчивается строка (то есть длина строки), не перемещаясь по ней, ища нулевой символ в конце. Ваша строка не может иметь нулей в ней. Таким образом, вы не можете сохранить произвольный двоичный кадр, например, изображение JPEG в строке C. Почему C-строки работают так? Это связано с тем, что микропроцессор PDP-7, на котором был изобретен язык программирования UNIX и C, имел тип строки ASCIZ. ASCIZ означало "ASCII с Z (ноль) в конце".

Это единственный способ хранения строк? Нет, на самом деле, это один из худших способов хранения строк. Для нетривиальных программ, API, операционных систем, библиотек классов вам следует избегать строк ASCIZ, таких как чума.

Ответ 2

Строки C представляют собой массивы символов, а массив C - это просто указатель на ячейку памяти, которая является начальным расположением массива. Но и длина (или конец) массива должна быть каким-то образом выражена; в случае строк используется нулевое прекращение. Другой альтернативой было бы так или иначе переносить длину строки вместе с указателем на память или помещать длину в первое расположение массива или что-то еще. Это просто вопрос конвенции.

Языки более высокого уровня, такие как Java или PHP, хранят информацию о размере с массивом автоматически и прозрачно, поэтому пользователю не нужно беспокоиться о них.

Ответ 3

Потому что в строках C всего лишь последовательность символов, к которым обращается viua указатель на первый символ.

В указателе для хранения длины нет места, поэтому вам нужно указать, где находится конец строки.

В C было решено, что это будет указано нулевым символом.

В pascal, например, длина строки записывается в байт, непосредственно предшествующий указателю, поэтому почему строки pascal имеют максимальную длину 255 символов.

Ответ 4

C не имеет понятия нитей сам по себе. Строки - это просто массивы символов (или wchars для unicode и т.д.).

Из-за этих фактов C не имеет возможности проверить, например, длину строки, поскольку нет длины "mystring- > ", где-либо нет значения длины. Единственный способ найти конец строки - перебрать ее и проверить на \0.

Существуют строковые библиотеки для C, которые используют такие структуры, как

struct string {
    int length;
    char *data;
};

чтобы удалить необходимость\0-завершения, но это не стандартное C.

Языки, такие как С++, PHP, Perl и т.д., имеют свои собственные внутренние строковые библиотеки, которые часто имеют отдельное поле длины, которое ускоряет некоторые строковые функции и устраняет необходимость в \0.

Некоторые другие языки (например, Pascal) используют строковый тип, который называется (suprisingly) Pascal String, он сохраняет длину в первом байте строки, что является причиной того, что эти строки ограничены длиной до 255 символов.

Ответ 5

Подумайте, какая память: смежный блок блоков размера байта, который может быть заполнен любыми битовыми шаблонами.

2a c6 90 f6

Символ - это просто один из этих битовых шаблонов. Его значение в виде строки определяется тем, как вы ее рассматриваете. Если вы посмотрели на одну и ту же часть памяти, но используя целочисленное представление (или какой-либо другой тип), вы получили бы другое значение.

Если у вас есть переменная, которая является указателем на начало кучки символов в памяти, вы должны знать, когда закончится эта строка, и начнется следующая часть данных (или мусора).

Пример

Посмотрим на эту строку в памяти...

H e l l o , w o r l d ! \0 
^
|
+------ Pointer to string

... мы видим, что строка логически заканчивается после символа !. Если бы не было \0 (или какого-либо другого метода для определения его конца), как бы мы знали, когда искали память, которую мы закончили с этой строкой? Другие языки несут длину строки со строковым типом, чтобы решить эту проблему.

Я задал этот вопрос, когда мои базовые знания о компьютерах были ограничены, и это ответ, который помог бы много лет назад. Надеюсь, это тоже поможет кому-то другому.:)

Ответ 6

Это соглашение - его можно было бы реализовать с помощью другого алгоритма (например, длина в начале буфера).

На "низкоуровневом" языке, таком как ассемблер, легко проверить "NULL" эффективно: это может облегчить решение идти с NULL завершенными строками, а не отслеживать счетчик длины.

Ответ 7

Они должны быть пустыми, чтобы вы знали, как долго они будут. И да, это просто массивы char.

Языки более высокого уровня, такие как PHP, могут выбрать, чтобы скрыть нулевое завершение от вас или не использовать его вообще - например, они могут содержать длину. C не делает этого таким образом из-за накладных расходов. Языки высокого уровня также не могут реализовывать строки как массив char - они могли (и некоторые из них) реализовывать их как списки массивов char, например.

Ответ 8

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

В таких языках, как PHP, Perl, С# и т.д. строки могут иметь или не иметь сложных структур данных, поэтому вы не можете предположить, что они имеют нулевой символ. В качестве надуманного примера у вас может быть язык, который представляет такую ​​строку:

class string
{
   int length;
   char[] data;
}

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

Ответ 9

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