2013-06-28 2 views
4

Я учил себя C++ в течение последних двух дней, чтобы подготовиться к первому году в качестве основного. Я сейчас на строках C-стиля и задаюсь вопросом, что такое точка нулевого терминатора.Почему нужен нулевой ограничитель?

Я понимаю, что это необходимо, но я думаю, что я просто не понимаю, почему строка не просто закончится на последнем знаке.

+3

Откуда вы знаете, что такое последний символ? – SLaks

+1

Вам нужен согласованный последний символ, в C это 0 байт. В ASM обычно это $ char. Вы знаете последний символ, но как компилятор знает, что вы думаете? –

ответ

17

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

Есть несколько способов узнать, где это «последний символ»:

  1. Магазин количество символов в строке отдельно от персонажей струны,
  2. Поместите маркер, который указывает на последний char строки, или
  3. Сохраните указатель на последний символ строки отдельно от символов строки.

C выберите второй маршрут; другие языки (Паскаль и т. д.) выбирают первый маршрут. Некоторые реализации C++ std::string выбирают третий маршрут *.


* Даже версии std::string, использующие первый или третий подход, завершают нулевые буферы для совместимости с частями C библиотеки. Это необходимо для обеспечения того, что c_str() возвращает действительную строку C.

+1

4. Сделайте все строки фиксированными массивами размерами, возможно дополненными пробелами. Но это безумие нужно претерпеть только в фортране. – cmaster

+0

Я думаю, что следует упомянуть, что даже если C++ 'string' обычно использует первое решение (или третье) по соображениям эффективности, так что ему не нужно пересчитывать длину строки каждый раз, когда это необходимо, она * все еще * использует второе решение также для поддержания совместимости строки с C API (при условии, что 'string' не содержит нулевые символы, которые являются законными с C++' string', но сокращают 'strlen' по сравнению с' string :: size() '). - По крайней мере, при вызове 'string :: c_str()' (хотя большинство реализаций, вероятно, только записывают нулевой ограничитель один раз, когда изменяется размер строки). – syam

+0

@syam Это замечательный комментарий, я отредактировал ответ, чтобы включить его. Благодаря! – dasblinkenlight

0

Поскольку строка в стиле c не знает, какой символ является последним символом. Например, если вы читаете имя, которое вы могли бы сделать буфер следующим образом:

char buf[256] // this allows c-style strings that contain 255 characters 

Но когда вы идете, чтобы заполнить этот буфер не может (скорее всего, не будет) использовать все пространство. Если вы заполните его «Джеком», единственная информация, о которой вы заботитесь, - это первые пять индексов, не все 256.

2

В C и C++ c-строки хранятся в массиве символов. Чтобы разрешить строки разной длины, эти массивы часто выделяются намного больше, чем фактические строки, которые они должны содержать. Например, программист может выделить массив char[256], который может содержать строку длиной от 0 до 255. Но компьютер должен знать, сколько времени на самом деле является строкой, поэтому оно должно заканчиваться нулевым персонаж. В противном случае было бы необходимо, чтобы длина массива символов была точно такой же, как строка (непрактичное решение, так как выделение и копирование памяти использует много ресурсов).

0

Рассмотрите каждый символ строки как блоки памяти в памяти. Если строка помещается в память. После этого рядом с ним помещается другая строка, тогда компьютер будет считать, что вторая строка присоединена к 1-й, если нуль отсутствует. Таким образом, null действует как ограничитель