 
        
        - •Лабораторная работа 1
- •Лабораторная работа 2 Переменные и константы. Базовые типы. Арифметические операции
- •Операции
- •Ввод и вывод данных
- •Лабораторная работа 3 Циклический и ветвящийся поток управления
- •Алгоритмы разветвляющейся структуры
- •Операторы выбора
- •Операторы циклов
- •Операторы перехода
- •Задание
- •Лабораторная работа 4 Функции. Вызов функций с формальными параметрами, передаваемыми по значению
- •Задание
- •Лабораторная работа 5 Одномерные массивы
- •Задание
- •Лабораторная работа 6 Многомерные массивы
- •Задание
- •Лабораторная работа 7 Функции для работы с символами
- •Лабораторная работа 8 Строки, литералы. Передача строк в функции
- •Строки и литералы
- •Библиотечные функции для работы со строками
- •Выделение памяти под строки
- •Передача строк в качестве параметров функций
- •Задание
- •Лабораторная работа 9 Указатели и динамические массивы
- •Задание
- •Варианты
- •Лабораторная работа 10 Динамические структуры данных
- •Структуры и указатели
- •Задание
- •Лабораторная работа 11 Объектно-ориентированное программирование. Создание классов и объектов
- •Задание
- •Лабораторная работа 12 Знакомство со средой быстрой разработки приложений. Использование компонент библиотеки vcl
- •Лабораторная работа 13 Вывод в форму результатов работы программы
- •Лабораторная работа 14 Изучение обработчиков событий компонентов библиотеки vcl
- •Лабораторная работа 15 Использование таймера для создания различных эффектов
- •Лабораторная работа 16 Рисование в канве. Построение графиков функций
- •Лабораторная работа 17 Изучение принципа работы текстового редактора
- •Список рекомендуемой литературы
- •Оглавление
Лабораторная работа 8 Строки, литералы. Передача строк в функции
Цель работы − приобрести навыки работы со строками и литералами в языке С++, получить практические навыки при передаче строк в функции.
Теория
Строки и литералы
Для того чтобы работать с текстом, в языке Си++ не существует особого встроенного типа данных. Текст представляется в виде последовательности знаков (байтов), заканчивающейся нулевым байтом.
Строки представляются в виде массива байтов.
Пример
char string[20];
string[0] = ’H’;
string[1] = ’e’;
string[2] = ’l’;
string[3] = ’l’;
string[4] = ’o’;
string[5] = 0;
В массиве string записана строка «Hello». При этом мы использовали только 6 из 20 элементов массива.
Для записи строковых констант в программе используются литералы. Литерал − это последовательность знаков, заключенная в двойные кавычки.
Пример
«Это строка»
«0123456789»
«*»
Заметим, что символ, заключенный в двойные кавычки, отличается от символа, заключенного в апострофы. Литерал «*» обозначает два байта: первый байт содержит символ звездочки, второй байт содержит ноль. Константа ’*’ обозначает один байт, содержащий знак звездочки.
| A | \0 | 
 | A | 
| ”A” − строка (2 байта) | 
 | ’A’ − символ (1 байт) | |
Рис. 8
С помощью литералов можно инициализировать массивы.
Пример
char alldigits[] = «0123456789»;
Размер массива явно не задан, он определяется исходя из размера инициализирующего его литерала, в данном случае 11 (10 символов плюс нулевой байт).
При работе со строками особенно часто используется связь между массивами и указателями. Значение литерала − это массив неизменяемых байтов нужного размера. Строковый литерал может быть присвоен указателю на char.
Пример
const char* message = «Сообщение программы»;
Значение литерала − это адрес его первого байта, указатель на начало строки. В следующем примере функция CopyString копирует первую строку во вторую.
Пример
void CopyString(char* src, char* dst) {
while (*dst++ = *src++)
*dst = 0; }
int main()
{
char first[] = «Первая строка»;
char second[100];
CopyString(first, second);
return 1;
}
Указатель на байт (тип char*) указывает на начало строки. Предположим, нам нужно подсчитать количество цифр в строке, на которую показывает указатель str.
Пример
#include
int k=0;
while (*str!= 0) //признак конца строки − ноль
{
if (isdigit(*str++)) //проверить байт, на который указывает
//str, и сдвинуть указатель на следующий
//байт
k++;
}
При выходе из цикла while переменная count содержит количество цифр в строке str, а сам указатель str указывает на конец строки − нулевой байт. Чтобы проверить, является ли текущий символ цифрой, используется функция isdigit. Это одна из многих стандартных функций языка, предназначенных для работы с символами и строками.
Библиотечные функции для работы со строками
С помощью функций стандартной библиотеки языка, которые содержатся в заголовочном файле string.h, реализованы многие часто используемые операции над символьными строками. В большинстве своем в качестве строк они воспринимают указатели. Прежде чем использовать эти указатели в программе, нужно подключить их описания с помощью оператора #include.
Здесь мы будем иметь дело с двумя группами функций. Функции с именами, начинающимися с str, работают с С-строками, в которых нулевой байт означает конец строки. Функции же, начинающиеся с mem, работают с массивами символов, следовательно, позволяют работать и с нулевыми байтами.
Обратите внимание – функции вроде копирования и слияния строк (модифицирующие один из аргументов) изменяют первый аргумент, а не второй. Приведем ряд наиболее употребительных функций для работы со строками (таблица).
| Прототип функции | Краткое описание | Примечание | 
| unsigned strlen(const char* s); | Вычисляет длину строки s | 
 | 
| int strcmp(const char* s1, const char* s2); | Сравнивает строки s1 и s2 | Если s1<s2, то результат отрицательный, если s1==s2, то результат равен 0, если s2>s1 – результат положительный | 
| int strcnmp(const char* s1, const char* s2); | Сравнивает первые n символов строк s1 и s2 | Если s1<s2, то результат отрицательный, если s1==s2, то результат равен 0, если s2>s1 – результат положительный | 
| char* strcpy(char* s1, const char* s2); | Копирует символы строки s1 в строку s2 | 
 | 
| char* strncpy(char* s1, const char* s2, int n); | Копирует n символов строки s1 в строку s2 | Конец строки отбрасывается или дополняется пробелами | 
| char* strcat(char* s1, const char* s2); | Приписывает строку s2 к строке s1 | 
 | 
| char* strncat(char* s1, const char* s2); | Приписывает первые n символов строки s2 к строке s1 | 
 | 
| char* strdup(const char* s); | Выделяет память и переносит в нее копию строки s | При выделении памяти используются функции | 
| char *strchr(char *s, int c) | Возвращает указатель на первый встреченный в строке символ c. Если такого символа в строке не оказалось, возвращает NULL | 
 | 
Продолжение табл.
| Прототип функции | Краткое описание | Примечание | 
| void *memcpy(void *dst, void *src, size_t len) | Копирует len байтов (включая нулевые) из src в dst. Возвращает dst | 
 | 
| void *memove(void *dst, void *src, size_t len) | Делает то же, что и memcpy | Это – единственная функция, которая по стандарту обязана правильно копировать перекрывающиеся объекты | 
| int memcmp(void *s1, void *s2, size_t len) | Аналог strcmp, но с учетом нулевых байтов | 
 | 
| void *memchr(void *s, int c, size_t len) | Аналог strchr, но с учетом нулевых байтов | 
 | 
| void *memset(void *s, int c, size_t len) | Заполняет первые len байтов массива s символом c | 
 | 
В следующем примере, использующем приведенные функции, в массиве result будет образована строка «1 января 1998 года, 12 часов».
Пример
char result[100];
char* date = «1 января 1998 года»;
char* time = «12 часов»;
strcpy(result, date);
strcat(result, «,»);
strcat(result, time);
Как видно из этого примера, литералы можно непосредственно использовать в выражениях.
Определить массив строк можно с помощью следующего объявления:
char* StrArray[5]={«one»,«two»,«three»,«four»,«five»};
