Столько, сколько я люблю C и C ++, я не могу не почесать голову при выборе строк с нулевым окончанием:
- Длина строки с префиксом (т.е. Паскаль) существовала до C
- Строки с префиксом длины ускоряют несколько алгоритмов, обеспечивая постоянный поиск по времени.
- Строки с префиксом длины затрудняют ошибки переполнения буфера.
- Даже на 32-битной машине, если вы позволите строке соответствовать размеру доступной памяти, строка с префиксом длины будет всего на три байта шире строки с нулевым символом в конце. На 16-битных машинах это один байт. На 64-битных компьютерах 4 ГБ - разумный предел длины строки, но даже если вы хотите расширить его до размера машинного слова, 64-битные машины обычно имеют достаточно памяти, что делает дополнительные семь байтов своего рода нулевым аргументом. Я знаю, что оригинальный стандарт C был написан для безумно плохих машин (с точки зрения памяти), но аргумент эффективности здесь не стоит.
- Практически все остальные языки (например, Perl, Pascal, Python, Java, C # и т. Д.) Используют строки с префиксом длины. Эти языки обычно превосходят C в тестах по обработке строк, потому что они более эффективны со строками.
- C ++ исправил это немного с помощью
std::basic_string
шаблона, но простые символьные массивы, ожидающие строки с нулевым символом в конце, все еще распространены. Это также несовершенно, поскольку требует выделения кучи. - Строки с нулевым символом в конце должны зарезервировать символ (а именно, ноль), который не может существовать в строке, в то время как строки с префиксом длины могут содержать встроенные нули.
Некоторые из этих вещей стали известны позже, чем C, поэтому для C было бы разумно не знать о них. Тем не менее, некоторые были просто задолго до того, как появился С. Почему были выбраны строки с нулевым символом в конце вместо явно превосходящего префикса длины?
РЕДАКТИРОВАТЬ : Так как некоторые просили факты (и не нравились те, которые я уже предоставил) в моем пункте эффективности выше, они вытекают из нескольких вещей:
- Concat, использующий строки с нулевым символом в конце, требует O (n + m) временной сложности. Длина префикса часто требует только O (м).
- Длина с использованием строк с нулевым символом в конце требует O (n) временной сложности. Длина префикса O (1).
- Длина и конкат являются наиболее распространенными строковыми операциями. Есть несколько случаев, когда строки с нулевым символом в конце могут быть более эффективными, но они встречаются гораздо реже.
Из ответов ниже приведены некоторые случаи, когда строки с нулевым символом в конце более эффективны:
- Когда вам нужно обрезать начало строки и нужно передать ее какому-либо методу. Вы не можете делать это в постоянное время с префиксом длины, даже если вам разрешено уничтожать исходную строку, потому что префикс длины, вероятно, должен следовать правилам выравнивания.
- В некоторых случаях, когда вы просто просматриваете строку за символом, вы можете сохранить регистр процессора. Обратите внимание, что это работает только в том случае, если вы не распределяете строку динамически (потому что тогда вам придется освободить ее, что потребует использования того регистра ЦП, который вы сохранили, для хранения указателя, который вы изначально получили от malloc и друзей).
Ничто из вышеперечисленного не встречается так часто, как длина и конкат.
В ответах ниже утверждается еще одно:
- Вам нужно отрезать конец строки
но это неверно - это одинаковое количество времени для строк с нулевым символом в конце и длиной с префиксом. (Строки с нулевым символом в конце просто вставляют ноль там, где вы хотите, чтобы новый конец был, префиксы длины просто вычитают из префикса.)