Ru/String: Difference between revisions
(версия перевода 1.5) |
Kestrelguy (talk | contribs) (updated language bar. also some formatting. still has a couple stray English lines.) |
||
Line 1: | Line 1: | ||
{{ | {{lang|String|title=Строка (string)}}[[Category:Glossary:ru]][[category:Variables:ru]] | ||
{{finishtranslation:ru}} | |||
| | |||
|title=Строка(string) | |||
}} | |||
{{toc-right}} | {{toc-right}} | ||
[[W: | [[W:ru:Массив (тип данных)|Массивы]] {{ent:ru|char}} ([[W:ru:ASCII|ASCII]]) или <tt>wchar_t</tt> ([[W:ru:Юникод|Юникод]]) обычно используют для хранения текста. У этих хранилищ есть специальный термин:''' [[W:ru:Строковый тип|strings (строки)]]''', или иногда «C strings (строки)». Они сложны и важны. | ||
== Нулевой Терминатор == | == Нулевой Терминатор == | ||
''' Строки всегда на один символ больше, чем они есть. Экстра-символ это Нулевой (бинарный нуль, пишется как <code>\0</code>).''' Это необходимо, потому что [[pointer]] {{en}} (указатель) на строку передаётся по кругу, а не полностью, указатель не содержит данных о длине строки. | |||
''' Строки всегда на один символ больше, чем они есть. Экстра-символ это Нулевой (бинарный нуль, пишется как <code>\0</code>).''' Это необходимо, потому что [[pointer]] (указатель) на строку передаётся по кругу, а не полностью, указатель не содержит данных о длине строки. | |||
Без терминатора было бы сложно понимать, где строка заканчивается, а где начинается следующая переменная, или нераспределённая память. Вот что такое переполнение буфера, и это очень плохо! | Без терминатора было бы сложно понимать, где строка заканчивается, а где начинается следующая переменная, или нераспределённая память. Вот что такое переполнение буфера, и это очень плохо! | ||
{{Note:ru|Нулевой Терминатор не должен быть последним предметом в конце массива. Байты после него будут просто проигнорированными функцией string-handling.}} | {{Note:ru|Нулевой Терминатор не должен быть последним предметом в конце массива. Байты после него будут просто проигнорированными функцией string-handling.}} | ||
== Создание из строкового литерала == | == Создание из строкового литерала == | ||
<source lang=cpp> | <source lang=cpp> | ||
char* MyString = "Hello world"; // должен быть присвоен указатель! | char* MyString = "Hello world"; // должен быть присвоен указатель! | ||
</source> | </source> | ||
Этот код создаёт строку из [[W:string literal|строки литерала]]. Двойная квота помечает специальные синтаксисы, которые генерируют массив <code>char</code> из его контента. Поэтому код выше: | Этот код создаёт строку из [[W:string literal|строки литерала]] {{en}}. Двойная квота помечает специальные синтаксисы, которые генерируют массив <code>char</code> из его контента. Поэтому код выше: | ||
# Назначает произвольные 12 байтов памяти на хранение строки. Это один на каждый символ, плюс автоматически делает двенадцатый для нулевого теринатора. | # Назначает произвольные 12 байтов памяти на хранение строки. Это один на каждый символ, плюс автоматически делает двенадцатый для нулевого теринатора. | ||
# Создаёт локальный <code>char</code> [[ | # Создаёт локальный <code>char</code> [[Accessing Other Entities#Pointer|указатель]] {{en}}, который хранит адрес первого символа (H в нашем случае). | ||
Строки литералы часто передаются переменной {{ent|W:ru:Const (программирование)|alt=const}}. Потому что строка литерал останется в памяти до конца. | |||
{{Note:ru|Если вы изучите <code>MyString</code> в Visual Studio отладчике, то вы увидите сроку полностью. Это специальное поведение, чтобы облегчить изучение строки; грубо говоря, оно должно просто показать вам указатель (то есть первый символ, H).}} | {{Note:ru|Если вы изучите <code>MyString</code> в Visual Studio отладчике, то вы увидите сроку полностью. Это специальное поведение, чтобы облегчить изучение строки; грубо говоря, оно должно просто показать вам указатель (то есть первый символ, H).}} | ||
== Создание по размеру == | == Создание по размеру == | ||
<source lang=cpp> | <source lang=cpp> | ||
char MyString[12]; // позволяет только статический размер | char MyString[12]; // позволяет только статический размер | ||
Line 43: | Line 34: | ||
</source> | </source> | ||
Этот код выделяет две 12-байтовые строки, но не вставляет ничего в них (так что их содержание будет или пустым, или брехнёй). They need to be assigned to, ideally with a string function like <code>strcpy()</code> или < | Этот код выделяет две 12-байтовые строки, но не вставляет ничего в них (так что их содержание будет или пустым, или брехнёй). They need to be assigned to, ideally with a string function like <code>strcpy()</code> или <tt>sprintf()</tt>. | ||
== | Разность между ними это то, что они создают массив в пространстве памяти функции, пока остальные создают указатель в функции и используют {{ent|W:ru:new (C++)|alt=new}} для распределения их же строк в других местах. Преимущество <code>new</code> в том, что вы можете выделить массив размера, определенного во время выполнения, но плохо, что вы не скрупулёзны в вызове {{ent:ru|W:delete (C++)|alt=delete}} (или <code>delete[]</code> массивов) или вы получите [[W:ru:Утечка памяти|утечку памяти]]. | ||
{{Note:ru|Source это внутренне ASCII. Единственный раз, когда вы будете работать с Unicode, это тогда, когда вы углубитесь во внутреннюю работу [[VGUI]].}} | == Строки Юникод == | ||
{{Note:ru|Source это внутренне ASCII. Единственный раз, когда вы будете работать с Unicode, это тогда, когда вы углубитесь во внутреннюю работу [[:Category:VGUI:ru|VGUI]].}} | |||
[[W: | [[W:ru:Юникод|Юникод]] начинают вести себя аналогично ASCII строкам, но заместо массива <tt>wchar_t</tt>. Они управляют самими собой Они управляются своим набороми строковых функций, обычно с 'wc' или ' wcs '(wide char string) в их имени. | ||
<source lang=cpp> | <source lang=cpp> | ||
Line 57: | Line 47: | ||
</source> | </source> | ||
<code>L</code> помечает строку литерал как | <code>L</code> помечает строку литерал как Юникод. Вам надо делать это хотя бы если все символы ASCII-совместимы. | ||
== Функии строки == | == Функии строки == | ||
Есть множество функций которые, обрабатывают строки, из которых большинство распространённых ASCII вариантов имеют специфические Source <code>V_*</code> эквиваленты. Смотрите [https://docs.microsoft.com/ru-ru/cpp/c-runtime-library/string-manipulation-crt MSDN] для более комплексного листа, или поищите VS' Просмотр Классов для «V_str». | |||
Есть множество функций которые, обрабатывают строки, из которых большинство распространённых ASCII вариантов имеют специфические Source <code>V_*</code> эквиваленты. Смотрите [ | |||
Revision as of 21:10, 6 June 2022
Массивы char (ASCII) или wchar_t (Юникод) обычно используют для хранения текста. У этих хранилищ есть специальный термин: strings (строки), или иногда «C strings (строки)». Они сложны и важны.
Нулевой Терминатор
Строки всегда на один символ больше, чем они есть. Экстра-символ это Нулевой (бинарный нуль, пишется как \0
). Это необходимо, потому что pointer (указатель) на строку передаётся по кругу, а не полностью, указатель не содержит данных о длине строки.
Без терминатора было бы сложно понимать, где строка заканчивается, а где начинается следующая переменная, или нераспределённая память. Вот что такое переполнение буфера, и это очень плохо! Template:Note:ru
Создание из строкового литерала
char* MyString = "Hello world"; // должен быть присвоен указатель!
Этот код создаёт строку из строки литерала . Двойная квота помечает специальные синтаксисы, которые генерируют массив
char
из его контента. Поэтому код выше:
- Назначает произвольные 12 байтов памяти на хранение строки. Это один на каждый символ, плюс автоматически делает двенадцатый для нулевого теринатора.
- Создаёт локальный
char
указатель, который хранит адрес первого символа (H в нашем случае).
Строки литералы часто передаются переменной const. Потому что строка литерал останется в памяти до конца. Template:Note:ru
Создание по размеру
char MyString[12]; // позволяет только статический размер
int StringLen = 12;
char* pMyString = new char[StringLen]; // позволяет вставить размер из переменной
delete[] pMyString; // всегда удаляет (delete / delete[]) всё созданное с 'new' после использования
Этот код выделяет две 12-байтовые строки, но не вставляет ничего в них (так что их содержание будет или пустым, или брехнёй). They need to be assigned to, ideally with a string function like strcpy()
или sprintf().
Разность между ними это то, что они создают массив в пространстве памяти функции, пока остальные создают указатель в функции и используют new для распределения их же строк в других местах. Преимущество new
в том, что вы можете выделить массив размера, определенного во время выполнения, но плохо, что вы не скрупулёзны в вызове delete (или delete[]
массивов) или вы получите утечку памяти.
Строки Юникод
Юникод начинают вести себя аналогично ASCII строкам, но заместо массива wchar_t. Они управляют самими собой Они управляются своим набороми строковых функций, обычно с 'wc' или ' wcs '(wide char string) в их имени.
wchar_t* MyWideString = L"Здравей свят";
L
помечает строку литерал как Юникод. Вам надо делать это хотя бы если все символы ASCII-совместимы.
Функии строки
Есть множество функций которые, обрабатывают строки, из которых большинство распространённых ASCII вариантов имеют специфические Source V_*
эквиваленты. Смотрите MSDN для более комплексного листа, или поищите VS' Просмотр Классов для «V_str».