- •Лабораторная работа №3
- •Ход работы
- •1. Разработка спецификаций функции.
- •2. Разработка алгоритма решения.
- •3. Функция substr(). Текст программы.
- •Return ret;
- •4. Функция main()
- •Char s1[80];
- •Char s2[80];
- •Char *s1;
- •4.2. Текст функции main()
- •Cin.Getline(s1,80);
- •If (!strcmp(s1,"***")) break;
- •4.3. Общие объявления
- •Варианты индивидуальных заданий
- •Содержание отчёта
Лабораторная работа №3
Тема: указатели, символьные строки и функции.
Цель: закрепить навыки работы с указателями символьными строками и функциями пользователя
Ход работы
Необходимо разработать функцию для обработки символьной строки, которая определена в индивидуальном задании. При реализации функции запрещается пользоваться функциями библиотек языка C++.
Рассмотрим пример реализации функции, которая выделяет из заданной строки подстроку заданной длины, начиная с заданной позиции.
1. Разработка спецификаций функции.
Назовем функцию, которую мы создаем substr(). Состав и типы ее параметров достаточно просто могут быть определены из задания: это должны быть строка-источник данных (src), строка-результат (dest), начальная позиция (pos) и длина результата (len).
Строки должны быть определены в той функции, которая вызывает нашу функцию, следовательно, функции substr() передаются указатели на эти строки. Остальные параметры должны быть целыми числами.
Память для строки-источника лучше всего выделить во внешней функции. То же самое мы делаем и для строки-результата. Так как если мы объявим строку-результат как локальную в функции substr(), то память для нее будет выделена в нашей функции, и эта память будет освобождена, когда выполнение функции закончится, следовательно, та функция, которая вызвала нашу функцию, воспользоваться результатом не сможет. Если же мы выделим память в нашей функции явным образом (с помощью malloc()), то память сохранится, но тогда на ту функцию, которая вызвала нашу, возлагается обязанность явным образом освободить эту память, когда строка-результат уже не будет нужна.
Проанализируем возможности некорректного задания параметров при вызове функции. Во-первых, параметры pos и len не могут иметь отрицательного значения - оно просто не имеет смысла. Во-вторых, возможно такое значение параметра pos, которое будет превышать длину строки-источника. Будем считать все эти случаи ошибочным заданием параметров. Что должна делать функция при ошибочном задании параметров? Можно предложить три варианта: 1. Функция аварийно завершает работу всей программы. 2. Функция никак не реагирует на ошибку. 3. Функция возвращает какой-то признак ошибки.
Из этих вариантов мы выбираем третий, исходя из тех соображений, что функция может использоваться в большом числе программ, так что пусть внешняя программа, получив признак ошибки, сама принимает решение о дальнейших действиях при ошибке. А если так, то наша функция должна возвращать признак ошибки. Удобно сделать этот признак именно тем значением, которое функция возвращает.
Установим, что это значение будет 0 при нормальной работе функции, а при ошибке в параметрах это значение будет -1, а строка-результат будет пустой.
Возможен еще один вариант некорректного задания параметров - когда начало подстроки лежит в пределах строки-источника, а конец выходит за ее конец. Договоримся не считать этот случай фатальной ошибкою, пусть в этом случае функция формирует результат меньшей длины, чем задано и возвращает 1.
Еще одна проблема: если память для результата выделяет внешняя функция, что делать, если длина результата будет больше объема выделенной памяти? Чтобы контролировать эту ситуацию нужно ввести еще один параметр функции - максимальную длину строки-результата, а это нежелательно. Примем решение не контролировать такую ситуацию, перекладывая ответственность за нее на ту функцию, которая вызывает нашу. Это решения базируется на том, что именно так поступают и библиотечные функции языка С.
В итоге разработки спецификации для функции мы формулируем такое описание функции substr():
int substr(
char *src,
char *dest,
int pos,
int len);