C-строки — различия между версиями
Ulysses (обсуждение | вклад) м (переименовал «C-строки, массивы и указатели» в «C-строки») |
Ulysses (обсуждение | вклад) м (→Запись значений C-строк: поправлены отступы в листинге) |
||
(не показано 5 промежуточных версий этого же участника) | |||
Строка 1: | Строка 1: | ||
− | === | + | '''Определение.''' C-строкой называется массив char, содержащий символ с нулевым кодом (байт, у которого все биты равны 0), этот символ традиционно используется как маркер конца строки. |
+ | |||
+ | Сам нулевой байт не считается частью строки (например, длина C-строки, представленной массивом, у которого первый же байт нулевой, считается равной нулю). Из-за того, что длина C-строки изначально неизвестна, обработка строк обычно отличается от работы с обычными массивами через индексы. А именно, здесь используются указатели: | ||
+ | <source lang="cpp">for (char * p = str; *p != 0; ++p) { /* ... */ }</source> | ||
+ | <source lang="cpp">while (*p++) { /* ... */ }</source> | ||
+ | |||
+ | === Примеры === | ||
<source lang="cpp">// Вычисление длины строки | <source lang="cpp">// Вычисление длины строки | ||
int string_length(char * s) { | int string_length(char * s) { | ||
Строка 19: | Строка 25: | ||
} | } | ||
}</source> | }</source> | ||
− | Третий, | + | Третий, довольно распространённый вариант цикла по всей строке выглядит так: |
− | <source lang="cpp">while (*s | + | <source lang="cpp">while (*s) { |
− | // работа с очередным символом строки: *s | + | // работа с очередным символом строки: *s и в какой-то момент увеличение адреса: ++s / s++ |
+ | // часто бывает совмещено: *s++ / *++s | ||
}</source> | }</source> | ||
− | === | + | Ввиду того, что увеличение адреса может выполняться где-угодно в теле цикла (в отличие от for, в котором оно обычно выполняется в заголовке), такой цикл может быть более труден для понимания и поиска в нём ошибок. Однако если тело цикла не велико (одна-две строчки), то в большинстве случаев опытный C-программист выберет именно while. |
− | <source lang="cpp"> | + | |
− | + | ===Запись значений C-строк=== | |
− | + | [[Ввод_C-строк_с_клавиатуры|C-строки можно вводить с клавиатуры]], заботясь о том, чтобы памяти соответствующего массива было достаточно для хранения введённой строки вместе с нулевым байтом. Кроме того, C-строки можно инициализировать строковыми литералами (последовательность символов, заключённая в двойные кавычки): | |
− | + | <source lang="cpp"> | |
− | + | const char * s = "Hello, world"; // (1) указатель на константу типа char, то есть мы не можем менять строку | |
− | + | char s[] = "Goodbye, world"; // (2) можем менять строку</source> | |
+ | В обоих случаях вы получаете корректную C-строку, то есть массив символов, заканчивающихся нулевым байтом, однако '''в первом случае — массив константный, во втором — изменяемый'''. | ||
+ | |||
+ | Если C-строке не было задано значение при объявлении, строковый литерал в неё можно запись с помощью стандартной функции [http://www.cplusplus.com/reference/cstring/strcpy/ strcpy]: | ||
+ | <source lang="cpp">strcpy(s, "Hello, world") // s должен указывать на массив достаточной длины </source> | ||
+ | |||
+ | Печать C-строк осуществляется, как обычно, с помощью cout. | ||
+ | <source lang="cpp">cout << s << endl;</source> | ||
− | + | [[Категория:C++]] | |
− | |||
− | |||
− | |||
− |
Текущая версия на 20:29, 10 октября 2014
Определение. C-строкой называется массив char, содержащий символ с нулевым кодом (байт, у которого все биты равны 0), этот символ традиционно используется как маркер конца строки.
Сам нулевой байт не считается частью строки (например, длина C-строки, представленной массивом, у которого первый же байт нулевой, считается равной нулю). Из-за того, что длина C-строки изначально неизвестна, обработка строк обычно отличается от работы с обычными массивами через индексы. А именно, здесь используются указатели:
for (char * p = str; *p != 0; ++p) { /* ... */ }
while (*p++) { /* ... */ }
Примеры
// Вычисление длины строки
int string_length(char * s) {
int len = 0;
// Цикл закончится при достижении нулевого байта, обозначающего конец строки
for ( ; *s != 0; ++s)
++len;
return len;
}
// Каждая латинская буква, кроме 'z', меняется на следующую в алфавите
void shift_string(char * s) {
for ( ; *s; ++s) { // Ненулевое значение кода символа преобразуется к True
// Этот заголовок цикла работает также, как в string_length
if ('a' <= *s && *s < 'z')
++(*s); // Увеличение кода символа на единицу
}
}
Третий, довольно распространённый вариант цикла по всей строке выглядит так:
while (*s) {
// работа с очередным символом строки: *s и в какой-то момент увеличение адреса: ++s / s++
// часто бывает совмещено: *s++ / *++s
}
Ввиду того, что увеличение адреса может выполняться где-угодно в теле цикла (в отличие от for, в котором оно обычно выполняется в заголовке), такой цикл может быть более труден для понимания и поиска в нём ошибок. Однако если тело цикла не велико (одна-две строчки), то в большинстве случаев опытный C-программист выберет именно while.
Запись значений C-строк
C-строки можно вводить с клавиатуры, заботясь о том, чтобы памяти соответствующего массива было достаточно для хранения введённой строки вместе с нулевым байтом. Кроме того, C-строки можно инициализировать строковыми литералами (последовательность символов, заключённая в двойные кавычки):
const char * s = "Hello, world"; // (1) указатель на константу типа char, то есть мы не можем менять строку
char s[] = "Goodbye, world"; // (2) можем менять строку
В обоих случаях вы получаете корректную C-строку, то есть массив символов, заканчивающихся нулевым байтом, однако в первом случае — массив константный, во втором — изменяемый.
Если C-строке не было задано значение при объявлении, строковый литерал в неё можно запись с помощью стандартной функции strcpy:
strcpy(s, "Hello, world") // s должен указывать на массив достаточной длины
Печать C-строк осуществляется, как обычно, с помощью cout.
cout << s << endl;