Опубликован: 03.09.2010 | Уровень: для всех | Доступ: свободно
Лекция 3:

Типы данных, определяемые программистом

< Лекция 2 || Лекция 3: 12345 || Лекция 4 >

Двумерные массивы

Элемент массива может быть любого типа, кроме файлового, следовательно, он может быть и массивом, например:

const n = 4; m = 3;
type mas  = array [1 .. n] of integer;    
     mas2 = array [1 .. m] of mas;

Более компактно это можно записать так:

type mas2 = array [1 .. m, 1 .. n] of integer;

Здесь описан тип массива, состоящего из m массивов, каждый из которых содержит n целых чисел. Иными словами, это матрица из m строк и n столбцов ( рис. 3.1). Обе размерности массива должны быть константами или константными выражениями. Имя типа указывается при описании переменных, например:

var a, b : mas2;

В памяти двумерный массив располагается по строкам.

a11  a12  a13  a14  a21  a22   a23  a24  a31  a32  a33  a34
|  – 1–я строка –   |   – 2–я строка –    |   – 3–я строка –   |

Строки массива ничем не отделены одна от другой, то есть прямоугольной матрицей двумерный массив является только в нашем воображении. При просмотре массива от начала в первую очередь изменяется правый индекс (номер столбца).

 Матрица из m строк и n столбцов

Рис. 3.1. Матрица из m строк и n столбцов

К элементу двумерного массива обращаются, указывая номер строки и номер столбца, на пересечении которых он расположен, например:

a[1, 4] b[i, j] b[j, i]

ВНИМАНИЕ Компилятор воспринимает как номер строки первый индекс, как бы он ни был обозначен в программе.

При инициализации двумерных массивов каждая строка заключается в дополнительную пару круглых скобок, например:

const a : mas2 = ( ( 2, 3, 1, 0),
                   ( 1, 9, 1, 3),
                   ( 3, 5, 7, 0)  );

С массивами в целом определена только одна операция — присваивание массивов одного типа (например, b := a ) . Все остальные действия выполняются с отдельными элементами. Например, чтобы ввести с клавиатуры двумерный массив, необходимо организовать вложенные циклы:

for i := 1 to m do
    for j := 1 to n do read(a[i, j]);

В соответствии с приведенным здесь порядком следования циклов элементы массива должны вводиться по строкам (при этом неважно, как будут располагаться элементы массива, важен только порядок их следования).

Пример. Программа, которая для целочисленной матрицы 3x4 определяет среднее арифметическое ее элементов и количество положительных элементов в каждой строке.

Для нахождения среднего арифметического порядок перебора элементов массива (по строкам или по столбцам) роли не играет. Нахождение количества положительных элементов каждой строки требует просмотра матрицы по строкам ( пример 3.3).

program sred_n;
const m = 3; n = 4;
var a : array [1 .. m, 1 .. n] of integer;
    i, j, n_pos_el : integer;
    sred : real;
begin
    for i := 1 to m do
    for j := 1 to n do read(a[i, j]);
    sred := 0;
    for i := 1 to m do begin
        n_pos_el := 0;
        for j := 1 to n do begin
            sred := sred + a[i, j];
            if a[i, j] > 0 then inc(n_pos_el);
        end;
        writeln('В ', i, '–й строке ', n_pos_el, ' положительных элементов');
    end;
    sred := sred / m / n;
    writeln('Среднее арифметическое: ', sred:6:2);
end.
Листинг 3.3.
СОВЕТ Записывайте операторы инициализации накапливаемых в цикле величин непосредственно перед циклом, в котором они вычисляются.

Строки

Строки используются для хранения последовательностей символов. В Паскале существует три типа строк:

  1. стандартные ( string );
  2. определяемые программистом на основе string ;
  3. строки в динамической памяти

Строка типа string может содержать до 255 символов. Под каждый символ отводится по одному байту, в котором хранится код символа. Еще один байт отводится под фактическую длину строки. Таким образом, в памяти под одну переменную типа string всегда отводится 256 байт.

Для коротких строк использовать стандартную строку неэффективно, поэтому есть возможность самостоятельно задавать максимальную длину строки, которая должна быть константой или константным выражением. Например, ниже описан собственный тип данных с именем str4:

type str4 = string [4]; { переменная такого типа занимает в памяти 5 байтов }

Примеры описания строк:

const n = 15;
var s : string;         { строка стандартого типа }
    s1 : str4;          { строка типа str4, описанного выше }
    s2 : string [n];    { описание типа задано при описании переменной }

Инициализация строк, как и переменных других типов, выполняется в разделе описания констант.

const s3 : string [15] = 'shooshpanchik';

Внутреннее представление строки s3 представлено на рис. 3.2.

 Внутреннее представление строки s3

Рис. 3.2. Внутреннее представление строки s3

Операции

Строки можно присваивать друг другу. Если максимальная длина результирующей строки меньше длины исходной, лишние символы справа отбрасываются.

s2 := 'shooshpanchik'; 
s1 := s2;                  { в s1 будут помещены символы "shoo" }

Строки можно склеивать (сцеплять) между собой с помощью операции конкатенации, которая обозначается знаком +, например:

s1 := 'ком';
s2 := s1 + 'пот';                        { результат — "компот" }

Строки можно сравнивать друг с другом с помощью операций отношения. При сравнении строки рассматриваются посимвольно слева направо, при этом сравниваются коды соответствующих пар символов. Строки равны, если они имеют одинаковую длину и посимвольно эквивалентны. В строках разной длины существующий символ всегда больше соответствующего ему отсутствующего символа.

'abc' > 'ab' 'abc' = 'abc' 'abc' < 'abc '

Имя строки может использоваться в процедурах ввода-вывода:

readln (s1, s2); write (s1);

При вводе в строку считывается из входного потока количество символов, равное длине строки или меньшее, если символ перевода строки (который вводится нажатием клавиши Enter ) встретится раньше. При выводе под строку отводится количество позиций, равное ее фактической длине.

К отдельному символу строки можно обращаться как к элементу массива символов, например s1[4] . Символ строки совместим с типом char, их можно использовать в выражениях одновременно, например:

s1[4] := 'x'; writeln (s2[3] + s2[5] + 'r');

Процедуры и функции для работы со строками

При работе со строками, как правило, возникает необходимость выполнять их копирование, вставку, удаление или поиск. Для эффективной реализации этих действий в Паскале предусмотрены стандартные процедуры и функции. Они кратко описаны ниже.

Функция Concat (s1, s2, ..., sn) возвращает строку, являющуюся слиянием строк s1, s2, ..., sn.

Функция Copy (s, start, len) возвращает подстроку длиной len, начинающуюся с позиции start строки s.

Процедура Delete (s, start, len) удаляет из строки s, начиная с позиции start, подстроку длиной len.

Процедура Insert (subs, s, start) вставляет в строку s подстроку subs, начиная с позиции start.

Функция Length (s) возвращает фактическую длину строки s, результат имеет тип byte.

Функция Pos (subs, s) ищет вхождение подстроки subs в строку s и возвращает номер первого символа subs в s или нуль, если subs не содержится в s.

Процедура Str (x, s) преобразует числовое значение x в строку s, при этом для x может быть задан формат, как в процедурах вывода write и writeln.

Процедура Val (s, x, errcode) преобразует строку s в значение числовой переменной x, при этом строка s должна содержать символьное представление числа. В случае успешного преобразования переменная errcode равна нулю. Если же обнаружена ошибка, то errcode будет содержать номер позиции первого ошибочного символа, а значение x не определено.

Пример. Программа читает текст из файла и выводит его на экран, заменяя заданную с клавиатуры последовательность символов на многоточии ( пример 3.4).

program censor;
var s, str : string[10];
    f      : text;
    i, dl  : integer;
begin
    assign(f, 'primer.txt'); reset(f);
    writeln('Какую последовательность заменять?'); readln(s);
    dl := length(s);
    while not Eof(f) do begin
        readln(f, str);
        i := 1;
        while i <> 0 do begin
            i := Pos(s, str);
            if i <> 0 then begin
                Delete(str, i, dl); Insert('...', str, i);
            end;
        end;
        writeln(str);
    end;
    close(f)
end.
Листинг 3.4.
< Лекция 2 || Лекция 3: 12345 || Лекция 4 >
София Шишова
София Шишова

Я завершила экзамен 90 баллов на 5. Сертификат не заказала. Сейчас пытаюсь найти как его заказать. у меня указано экзамен пройден баллы оценка видно, а чтоб заказать сертификат нигде не видно.