
- •Лабораторная работа 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»};