Файл: Сравнительный анализ описания данных для различных языков программирования.pdf
Добавлен: 29.03.2023
Просмотров: 324
Скачиваний: 5
2.3. Строковые типы
В языке Qbasic cтроковый тип может содержать любые символы до 32767 знаков в кодировки ASCII. Для определения типа как строковый используется суффикс $. [6]
На практике это выглядит так:
NAMES$ = “ВАСЯ”(переменной NAMES при помощи суффикса $ присвоено строковое значение заключенное в двойные кавычки - ВАСЯ)
По аналогии с рассматриваемым выше оператором DEF используется в виде DEFSTR для присвоения типа строковые.[10] Принципы именования переменных и констант те же что и для численных типов. Разницы в регистре букв в названии имени не имеется. Для задания пустой строки используются двойные кавычки NAMES$ = “”
В языке Pascal тип данных строковый задается так же типом string. В Pascal длина стандартной строки ограничена 255 символами. Под каждый символ отводится по одному байту, в котором хранится код символа. Кроме того, каждая строка содержит еще дополнительный байт, в котором хранится длина строки, он имеет индекс 0. [17]Если заранее известно, что длина строки будет меньше 255 символов, то программист может сам задать максимальную длину строки.
сonst
a1: string = ‘строка’
a2: string = ‘2’
type
string_type = string[20];
var
b1, b2: string_type;
В этом примере задан тип строковый с ограничением длины строки в 20 символов, а переменным b1 и b2 задан созданный нами тип.
Надо обратить внимание что в отличии от Qbasic содержимое строки заключаются в одинарные кавычки (апострофы) ‘ ’(в данном случае у нас получена строка с нулевым значением).[17]
Для языка программирования С++ как таковой строковый тип отсутствует. Строки представляются последовательностью символов(литералов) заключенных в двойные кавычки "". Строковые константы в С++ являются по сути массивами символов типа char.[9] При этом в С++ присутствует класс string который содержит последовательность символов и предоставляет такие операции ка добавление символов к строке, определение длины, конкатенация и применяется при низкоуровневой обработке текстов. Чтобы иметь возможность работать со строками необходимо подключить класс #include <string>. [15]
Применимые операции для строковых данных в QBasic является операция конкатенация (+) служащая для объединения строк, сравнения (=, <>, <, >, <=, >=). Сравнение двух строк выполняется слева направо с учетом кодов ASCII. Сначала сравниваются коды первых символов, затем вторых и т.д. Если строки имеют одинаковую длину и одинаковую последовательность символов тогда они считаются равными. Результат операций сравнения имеет логический тип, то есть принимает значения истина (true - 1) или ложь (false - 0). Так же для строкового типа применимы различные функции: LEN - выдаёт количество символов, STRING$ - функция создания текстовой переменной любой длинны содержащей одинаковые символы, INSTR – функция выдаёт номер позиции вхождения подстроки в строку, ARPTR – функция выдаёт физический адрес переменной, LEFT$ - функция выдаёт n символов слева, RIGHT$ выдаёт n символов справа, LCASE переводит в маленькие буквы, UCASE наоборот в большие, LTRIM - выдаёт копию строки с удалёнными пробелами слева, RTRIM$ наоборот справа, SPACE$ - выдаёт строку с заданным количеством пробелов от 0 до 32767, MID$ - выбор или замены части символов переменной и д.р. Продемонстрируем некоторые операции со строковым типом на рисунке 5.
Рис. 5. Демонстрация операций со строковым типом в Qbasic
В языке Pascal для строк так же как и в Qbasic применимы операции конкатенации [14], их можно сравнивать с помощью операций отношения:
‘абв‘ > ‘аб‘ (true)
‘ абв‘ = ‘ абв‘ (true)
‘абв‘ < ‘абв ‘ (false)
Символы просматриваются слева на право, если одна строка меньше другой по длине, недостающие символы короткой строки заменяются символом с кодом 0.
Возможно присваивать значение строк друг другу [17], если при этом максимальная длина присеваемого значения больше чем то которому присваивается, то знаки справа игнорируются - рисунок 6.
Рис. 6. Операция присваивания строк в Pascal
При работе со строками можно пользоваться распространенными функциями и процедурами: concat (a1, a2, ..., an) для слияния строк, copy (a1, start, len) возвращает подстроку длиной len, начинающуюся с позиции start строки a1; delete (a1, start, len) удаляет из строки a1, начиная с позиции start, подстроку длиной len; insert (subst, a1, start) вставляет в строку s подстроку subst, начиная с позиции start; length (a1) возвращает фактическую длину строки a1, результат имеет тип byte; pos (subst, a1) ищет вхождение подстроки subst в строку a1 и возвращает номер первого символа subst в a1 или нуль, если subst не содержится в a1 и т.д.
2.4. Символьные типы
Символьные типы присутствуют в языках С++[15] и Pascal[17] и обозначаются типом char.
Это может быть буква, цифра или знак. Например, в типичном случае использования кодировки ASCII символу z соответствует число 122, а символу + число 43. Для типа char существуют две модификации signed char (то есть со знаком) принимающий значения от -128 до 127 и unsigned char (беззнаковый) принимающий значения от 0 до 255.
Следует отметить, что в случае необходимости иметь дело с переменными которые имеют значения русских букв, то их тип должен быть unsigned char, так как коды русских букв в кодировке ASCII обозначаются числами свыше 127, символ А (русская большая буква А) соответствует числу 128 и т.д. Символ заключается в одиночные кавычки и называется символьным литералом. Например для программы в кодировке ASCII символ ‘1’ воспринимается как целочисленное значение 49.
В С++ литеры в сочетание с обратным слэшем \, например, символ t - ‘\t’ используется как символ табуляции. Сочетания символов специально зарезервированы.[16]
Учитывая что есть множество различных языков со своими национальными алфавитами, количество букв и прочими особенностями имеется тип данных wchart_t который используется для более широкого диапазона кодов. В отличии от предыдущего тип wchart_t не является встроенным и его размер изменяется в зависимости от способов реализации. Он определяется с помощью оператора typedef. Так как типы wchart_t и char являются интегральными, то к ним можно применять логические побитовые и арифметические операции. В версии С++ начиная с C++11 были добавлены для поддержки д 16-битных и 32-битных символов Unicode были добавлены char16_t и char32_t.
В обоих языках символьный тип данных char занимает в памяти 1 байт и используется для хранения кода символа в одной из кодировок. Процесс объявления типа и присвоения значений аналогичен уже рассмотренным:
char x = ‘A’ (для С++)
x:char; (для Pascal)
a:=‘+’;
В Pascal так же как и в С++ тип char поддерживает полный набор символов ASCII, занимает в памяти 1 байт [14] и так же как и в С++ операторы сравнения могут использоваться применительно к типу char. Так же к символьному типу может применяться конкатенация (+).
К типу char в Pascal применимы 5 функций:[17] Ord - преобразовывает символ в её числовой код из таблицы ASCII; Chr – из номера в символ таблицы ASCII, Pred – для возврата значения предыдущего символа из таблицы ASCII, Succ - для вывода следующего и Upcase - преобразует строчные английские буквы в заглавные.
2.5. Тип void
Тип void существует только в языке С++ (применительно к рассматриваемым языкам). Это тип для которого не существует объектов. Он используется как часть более сложных типов. Используется в синтаксисе С++ для того чтобы проинформировать что у некоей функции не имеется возвращаемого значения т.к. по логике языка функция должна возвращать значение, то что у функции не имеется никаких параметров или в качестве указателя на неопределенные объекты.[15]
Примером использования будет служить маленькая игра для угадывания заранее заданной цифры на рисунке 7.
Рис. 7. Вариант использования типа void в С++
2.6. Перечисляемый тип
Перечисляемый тип используется в С++ (enum) это тип данных, который содержит определенный пользователем набор значений. [16]
Например, два перечисления enum Сolorflag {WHITE, BLUE, RED} и enum Month {JANUARY, FEBRUARY, … DECEMBER} являются различными типами данных Colorflag и Month. Каждый элемент определяется как целая константа и ему по умолчанию присваивается целое значение начиная с нуля. То есть в перечислении Colorflag первая константа WHITE имеет порядковый номер 0, а константа RED – 2, при этом все константы указанные в перечислении имеют тот же тип что и само перечисление - Colorflag. [15]
Поскольку значениями перечислителей являются целые числа, то их можно присваивать целочисленным переменным.
Этот тип широко используется в документировании кода.
Для Pascal для неявного задания перечисления можно использовать список значений:
type
Colorflag: (WHITE, BLUE, RED);
var
per: Colorflag;
К таким переменным можно применять функции ord, pred, succ и процедуры inc и dec и операции отношения.
2.7. Тип указатели
Тип указатели присутствует в языках С++[16] и Pascal[14].
Тип данных указатели – по сути дела такой тип, который содержит адрес какого то объекта (адрес первого байта этого объекта в памяти), это может быть переменная, функция, массив и др. Обязательное условие при объявлении указателя - надо задать тип соответствующий элементу на который он будет указывать [12]. Различие между именем и указателем заключается в том, что имя объекта прямо указывает на него, а указатель косвенно.
В памяти сам указатель занимает такой объем какой необходим для хранения адреса. Если у нас используется 32-битная архитектура, то указатель будет занимать 4 байта памяти, а в 64-битной 8 байт. Размер не будет зависеть от того на что он указывает.
С помощью указателей можно организовать массив, для выделения динамической памяти, указатели можно использовать чтобы передать большой объем данных без обязательного его копирования, например, от одной подпрограммы(функции) в другую подпрограмму, для передачи одной функции в качестве некого параметра в другую, используются в механизмах наследования и т.п.
В С++ указатели используются совместно с двумя операторами. Оператор & (оператор адреса) позволяет узнать адрес памяти который присвоен некоей переменной, оператор * (оператор разыменования) указать на адрес и получить значение находящееся по этому адресу. [12] Поясним на примере на рисунке 8 одновременно представив формы описания указателей.
Переменной с1 мы присвоили значение 124, следующим действием является создание указателя p который будет содержать адрес памяти где расположена с1, а результатом выполнения будет вывод значения переменной с2 с присвоенным ей значением.
Рис. 8. Пример использования указателей в С++
Указатели возможно использовать как операнды в арифметических выражениях (с ограничениями), выражениях сравнения и присваивания.[12]
Пример использования указателей с массивами и арифметических операций на рисунке 9.
Рис. 9. Использование указателей как операндов
Задан массив m состоящий из 6 значений. В первом случае указание на массив используется как указатель на его первый элемент, во втором случае на конкретный элемент массива под порядковым номером 2 (при этом необходимо учитывать что нумерация начинается с 0) и в конце «складывает» два указателя (на самом деле складываются значения на которые указывают указатели).
В Pascal для объявления указателей используется значок - ^.
Правила объявления аналогичны уже выше рассматриваемым:
p: ^char;
Для объявления переменных не связывая их, с каким либо типом данных можно использовать указатель без типа (pointer).[14]
p:pointer;
Для присваивания значения адреса используется оператор @ или адрес объекта с помощью функции ADDR.
p:= @X
Для работы с указателями в Pascal применяются различные функции и процедуры: ADDR(X) - результат POINTER, X –имя любой переменной, процедуры или функции; OFS(X):WORD - возвращает значение смещения адреса объекта X; SEG(X):WORD - возвращает значение сегмента адреса объекта X; CSEG(X):WORD, DSEG(X):WORD, SSEG(X):WORD, SPRT(X):WORD - возвращает текущее значение соответствующего регистра;
PRT(SEG,OFS) - преобразует отдельно заданные значение сегмента и смещения к типу указателя; MAXAVAIL:LONGINT - возвращает размер наибольшего непрерывного участка кучи; MEMXAVAIL:LONGINT - возвращает размер общего свободного пространства кучи.
Процедуры так же используются для работы с памятью – резервирования, уничтожения динамических переменных и возвращения в общую кучу фрагментов памяти зарезервированных указателями и т.п.[17]
2.8. Логические типы
Логический тип данных имеется в языках С++[16] и Pascal.[14]
Так как значение относится к типу целые, в памяти занимает 1 байт и его диапазон допустимых значений 256 знаков, для значения false определено число 0, а остальные от единицы до 255 это значение true. Таким образом выполняется false < true.
Для Pascal при объявлении логического типа используется boolean, для С++ bool. Правила объявления переменных такие же как и для остальных типов. Пример присвоения в Pascal:
x:=true;
y:=5>3;
В Pascal помимо операция отношения рассмотренных ранее имеются следующие логические операции: NOT – отрицание; OR – логическое объединение; AND – логическое пересечение; XOR – исключающее ИЛИ.[5]
В С++ данного типа используются следующие операции: && - логическое И, || - логическое ИЛИ, ! – логическое НЕ, а также возможны следующие операции отношения: > (больше), < (меньше), == (равно) следует обратить внимание что именно 2 символа = , >= (больше или равно), <= (меньше или равно) и != (не равно). [12]
Отсутствие в С++ логической операции ИЛИ в случае необходимости можно заменить использованием операции отношения !=.
При составлении сложных логических выражений имеющих своим значение тип boolean либо bool надо учитывать приоритет выполнения логических операций.[16], [17] Продемонстрируем это примером. Так как приоритет логического оператора (!)НЕ выше чем у отношения равенства, то в первом примере допущена ошибка, во втором же случае приоритет выполнения логического выражения правильно задан скобками. На рисунке 10 приведен пример неправильного и правильного составления логического выражения.