- •Основы программирования на языке Паскаль
- •Часть 1. Основы языка Паскаль 2
- •Часть 2. Элементы профессионального программирования на Паскале 44
- •От автора
- •Часть 1. Основы языка Паскаль
- •1. Алгоритм и программа
- •1.1. Алгоритм
- •1.2. Свойства алгоритма
- •1.3. Формы записи алгоритма
- •1.4. Программа и программное обеспечение
- •1.5. Этапы разработки программы
- •2. Данные в языке Паскаль
- •2.1 Константы
- •2.2 Переменные и типы переменных
- •3. Арифметические выражения
- •4. Линейный вычислительный процесс
- •4.1 Оператор присваивания
- •4.2 Оператор ввода
- •4.3 Оператор вывода
- •4.4 Управление выводом данных
- •4.5 Вывод на печать
- •5. Структура простой программы на Паскале
- •6. Компилятор и оболочка Turbo Pascal
- •7. Разветвляющийся вычислительный процесс и условный оператор
- •7.4. Короткий условный оператор
- •If логическое_выражение then оператор1;
- •7.5. Полный условный оператор
- •If логическое_выражение then оператор1
- •7.7. Вложенные условные операторы
- •7.9. Примеры программ с условным оператором
- •8. Директивы компилятора и обработка ошибок ввода
- •9. Оператор цикла. Циклы с предусловием и постусловием
- •10. Цикл со счетчиком и досрочное завершение циклов
- •11. Типовые алгоритмы табулирования функций, вычисления количества, суммы и произведения
- •11.1 Алгоритм табулирования
- •11.2 Алгоритм организации счетчика
- •11.3 Алгоритмы накопления суммы и произведения
- •12. Типовые алгоритмы поиска максимума и минимума
- •13. Решение учебных задач на циклы
- •14. Одномерные массивы. Описание, ввод, вывод и обработка массивов на Паскале
- •15. Решение типовых задач на массивы
- •Часть 2. Элементы профессионального программирования на Паскале
- •16. Кратные циклы
- •16.1 Двойной цикл и типовые задачи на двойной цикл
- •16.2 Оператор безусловного перехода
- •17. Матрицы и типовые алгоритмы обработки матриц
- •18. Подпрограммы
- •18.1 Процедуры
- •18.2 Функции
- •18.3 Массивы в качестве параметров подпрограммы
- •18.4 Открытые массивы
- •19. Множества и перечислимые типы
- •20. Обработка символьных и строковых данных
- •20.1. Работа с символами
- •20.2 Работа со строками
- •21. Текстовые файлы
- •21.1 Общие операции
- •21.2 Примеры работы с файлами
- •21.3 Работа с параметрами командной строки
- •22. Записи. Бинарные файлы
- •23. Модули. Создание модулей
- •23.1. Назначение и структура модулей
- •23.2. Стандартные модули Паскаля
- •24. Модуль crt и создание простых интерфейсов
- •25. Модуль Graph и создание графики на Паскале
- •Приложение 1. Таблицы ascii-кодов символов для операционных систем dos и Windows
- •Приложение 2. Основные директивы компилятора Паскаля
- •Приложение 3. Основные сообщения об ошибках Паскаля
- •Приложение 4. Дополнительные листинги программ
- •Приложение 5. Расширенные коды клавиатуры
- •Ascii‑коды
- •Расширенные коды
- •Приложение 6. Правила хорошего кода
- •Приложение 7. Рекомендуемая литература
20.2 Работа со строками
Строка - это массив символов, т.е. элементов типа char. В Паскале строке соответствует тип данных String.
var Имя_строки : string [Длина];
Если длина не указана, выделяется память под строку до 255 символов.
var s1:string;
s2:string[20];
s3:array [1..20] of string;
Здесь s2 – строка из 20 символов, s3 – массив из 20 строк, под каждую из которых будет выделено до 256 байт памяти (дополнительный байт нужен для хранения длины строки).
Операции со строками:
Присвоить строке значение - оператор присваивания.
s1:='А.И. Иванов';
s1[3]:=’В’; {символу присвоили символ!}
s2:='1999';
s3[1]:='Информатика';
s3[2]:='';
Ввести строку с клавиатуры: только оператор readln (т.к. ввод строки должен завершаться нажатием Enter!).
Вывести строку на экран: можно использовать как, Write так и Writeln
s2:='SUMMA';
Write (s2) ; - будет выведено SUMMA
Writeln ('Сумма':10); - будет выведено _ _ _ _ _ Сумма
Соединить 2 строки - оператор сложения.
s1:='1999' + ' год';
s3[3]:=s1+' '+s2;
Если при сложении строк превышена максимальная длина строки, лишние символы отсекаются. Можно также использовать стандартную функцию Concat.
Сравнить 2 строки: операции сравнения. Правила:
-
строки равны только при одинаковом наборе символов и одинаковой длине;
-
иначе происходит поэлементное сравнение символов по их кодам: '0'<'1'<...<'9'<'A'<...<'Z'<'a'<...<'z'<символы кириллицы
Стандартные подпрограммы обработки строк:
function Length (s:string):integer - определить длину строки в символах;
function Copy (str:string; N,L:integer): string - возвращает часть строки str длиной L, начиная с позиции N;
procedure Insert (s0:string; var s: string; N: integer) - в строку s вставляет строку s0, начиная с позиции N;
procedure Delete (var s:string; N,L:integer) - в строке s удаляет L символов, начиная с позиции N;
Function Pos (s0, s:string): integer - возвращает позицию, начиная с которой строка s0 содержится в строке s или 0, если s0 не содержится в s;
Procedure Str (X: real; var s:string);
Procedure Str (X: integer; var s:string) - преобразует число X в строку s;
Procedure Val (s:string; var X: real; var error:integer);
Procedure Val (s:string; var X: integer; var error:integer); - преобразует строку s в число X. Если преобразовать удалось, error=0, иначе error=номеру первого непреобразуемого символа.
Приведенных стандартных подпрограмм достаточно для большинства несложных задач, связанных с обработкой текстовых данных. Рассмотрим ряд типовых задач на примерах.
Пр: Разбираем предложение на слова и выводим каждое слово
var s,w:string;
p:integer;
begin
writeln ('Введите текст');
readln (s);
p:=1;
while p<>0 do begin
p:=pos (' ',s);
if p>0 then w:=copy (s,1,p-1)
else w:=s;
writeln (w);
delete (s,1,p);
end;
end.
Алгоритм работы этой программы очень прост - до тех пор, пока в строке s есть хотя бы один пробел, вся часть строки до пробела копируется в строковую переменную w (слово). Если пробелов уже нет, то вся строка – это одно слово. После обработки слова (в нашем случае – это вывод его на новую строку экрана оператором writeln) обработанная часть строки вместе с пробелом удаляются из s – чтобы следующий шаг цикла не нашел то же самое слово. Первый недостаток такого подхода – не учтены лишние пробелы между словами. Избавимся от них с помощью следующего примера.
Пр: Удаляем лишние пробелы между словами
{ . . . }
p:=1;
while p<>0 do begin
p:=pos (' ',s);
if p>0 then delete (s,p,1);
end;
if s[1]=' ' then delete (s,1,1);
if s[length(s)]=' ' then delete (s, length(s),1);
writeln (s);
Пока в строке есть два подряд идущих пробела, удаляем один из них. После этого остается проверить, нет ли в начале и конце строки по одному лишнему пробелу. Второй и более существенный недостаток приведенных примеров – проходы по строке неоднократны, тогда как разбор на слова можно сделать и за один цикл сканирования строки. Попытаемся реализовать это в следующей программе.
Пр. Разбираем предложение на слова за один цикл разбора.
var s,word:String;
c,c0:char;
i,l,start:integer;
inword:boolean;
begin
writeln ('Enter string:');
reset (input); readln (s);
s:=' '+s+' ';
l:=Length (s);
inword:=false;
for i:=2 to l do begin
c0:=s[i-1];
c:=s[i];
if (c0=' ') and (c<>' ') then begin
inword:=true;
start:=i;
end;
if (c=' ') or (c=#9) then begin
if inword=true then begin
word:=copy (s,start,i-start);
writeln ('''',word,''' is word');
end;
inword:=false;
end;
end;
end.
По сути дела, у нашей программы всего 2 состояния – внутри слова и вне его. Переключением состояний управляет флаг inword. Номер символа, с которого начинается очередное слово, запоминается в переменной start. Программа не учитывает знаки препинания и возможность разделения слов другими символами, кроме пробела. Тем не менее, избавившись еще и от функции copy, совершающей лишний проход по части строки (например, сразу же накапливая слово word по мере сканирования), можно было бы получить действительно эффективный алгоритм. Как обычно, платой за эффективность является сложность программы.
Пр. Работаем со строкой как с массивом символов (считаем кол-во пробелов в строке)
var s:string;
k,i:integer;
begin
writeln ('Text?');
readln (s);
k:=0;
for i:=1 to length (s) do
if s[i]=' ' then k:=k+1;
writeln ('k=',k);
end.