Реальные данные, с которыми работает программа, — это числа, строки и логические величины (аналоги 1 и 0, «да» и «нет», «истина» и «ложь»). Эти типы данных называют базовыми.
Каждая единица информации хранится в ячейках памяти компьютера, имеющих свои адреса. На практике заранее неизвестно, в каких конкретно ячейках памяти во время работы программы будут записаны ее данные, поэтому в языках программирования введено понятие переменной, позволяющее отвлечься от конкретных адресов и обращаться к содержимому памяти с помощью идентификатора или имени. В качестве таких имен,как правило, используется последовательности, содержащей английские буквы, цифры, символы подчеркивания и начинающейся не с цифры. Например:
Тип переменной (Вид числа) |
Бейсик |
Паскаль |
Си++ |
Числовой: |
|
|
|
Целое |
INTEGER |
integer |
Int |
Дробное |
DOUBLE |
real |
Float |
Логический |
Базового типа нет. Используется числовой тип INTEGER |
boolean |
bool |
Строчный |
Базового типа нет. Используется “” ? |
string |
string |
Запись |
|
record |
struct |
Очень большие или очень маленькие числа записываются специальным образом. Для них дополнительно указывается мантисса — число со знаком, являющееся степенью числа 10. Мантисса записывается справа от числа через букву е (или Е). Пробелы в такой записи не допускаются. Например, число 100 (единица, умноженная на 10 во второй степени) запишется так: 1е+2; число 0,003 (тройка, умноженная на 10 в минус третьей степени) так: Зе-3; число со 120 нулями — так: 1Е+120. Допускается дробная запись числа с мантиссой: 31.4е-1.
В языке ПАСКАЛЬ существует правило: тип явно задается в описании переменной или функции, которое предшествует их использованию. Концепция типа языка ПАСКАЛЬ имеет следующие основные свойства [10]:
-любой тип данных определяет множество значений, к которому принадлежит константа, которые может принимать переменная или выражение, или вырабатывать операция или функция;
-тип значения, задаваемого константой, переменной или выражением, можно определить по их виду или описанию;
-каждая операция или функция требует аргументов фиксированного типа и выдает результат фиксированного типа.
Отсюда следует, что транслятор может использовать информацию о типах для проверки вычислимости и правильности различных конструкций.
Тип определяет:
-возможные значения переменных, констант, функций, выражений, принадлежащих к данному типу;
-внутреннюю форму представления данных в ЭВМ;
-операции и функции, которые могут выполняться над величинами, принадлежащими к данному типу.
Обязательное описание типа приводит к избыточности в тексте программ, но такая избыточность является важным вспомогательным средством разработки программ и рассматривается как необходимое свойство современных алгоритмических языков высокого уровня. В языке ПАСКАЛЬ существуют скалярные и структурированные типы данных.
К cкалярным типам относятся стандартные типы и типы, определяемые пользователем.
Стандартные типы включают целые, действительные, символьный, логические и адресный типы. Типы, определяемые пользователем - перечисляемый и интервальный.
Структурированные типы имеют четыре разновидности: массивы, множества, записи и файлы.
Кроме перечисленных, TURBO PASCAL включает еще два типа - процедурный и объектный.
Из группы скалярных типов можно выделить порядковые типы, которые характеризуются следующими свойствами:
-все возможные значения порядкового типа представляют собой ограниченное упорядоченное множество;
-к любому порядковому типу может быть применена стандартная функция Ord, которая в качестве результата возвращает порядковый номер конкретного значения в данном типе;
-к любому порядковому типу могут быть применены стандартные функции Pred и Succ, которые возвращают предыдущее и последующее значения соответственно;
-к любому порядковому типу могут быть применены стандартные функции Low и High, которые возвращают наименьшее и наибольшее значения величин данного типа.
В языке ПАСКАЛЬ введены понятия эквивалентности и совместимости типов. Два типа Т1 и Т2 являются эквивалентными (идентичными), если выполняется одно из двух условий:
-Т1 и Т2 представляют собой одно и то же имя типа;
-тип Т2 описан с использованием типа Т1 с помощью равенства или последовательности равенств. Например:
type T1 = Integer; T2 = T1; T3 = T2;Менее строгие ограничения определены совместимостью типов. Например, типы являются совместимыми, если:
Integer('Z')представляет собой значение кода символа 'Z' в двухбайтном представлении целого числа, а
Byte(534)даст значение 22, поскольку целое число 534 имеет тип Word и занимает два байта, а тип Byte занимает один байт, и в процессе приведения старший байт будет отброшен.
К стандартным относятся целые, действительные, символьный и адресный типы.
Целые типы определяют константы, переменные и функции, значения которых реализуются множеством целых чисел, допустимых в данной ЭВМ.
тип диапазон значений требуемая памятьНад целыми операндами можно выполнять следующие арифметические операции: сложение, вычитание, умножение, деление, получение остатка от деления. Знаки этих операций:
Shortint -128 .. 127 1 байт Integer -32768 .. 32767 2 байта Longint -2147483648 .. 2147483647 4 байта Byte 0 .. 255 1 байт Word 0 .. 65535 2 байта
+ - * div modРезультат арифметической операции над целыми операндами есть величина целого типа. Результат выполнения операции деления целых величин есть целая часть частного. Результат выполнения операции получения остатка от деления - остаток от деления целых. Например:
Тип Диапазон Количество цифр Требуемая значений мантиссы память (байт) --------------------------------------------------------------- Real 2.9e-39 .. 1.7e+38 11 6 Single 1.5e-45 .. 3.4e+38 7 4 Double 5.0e-324 .. 1.7e+308 15 8 Extended 3.4e-4932 .. 1.1e+4932 19 10 Comp -9.2e+18 .. 9.2e+18 19 8 ---------------------------------------------------------------Тип Real определен в стандартном ПАСКАЛЕ и математическим сопроцессором не поддерживается.
Тип Comp хотя и относится к действительным типам, хранит только длинные целые значения.
Над действительными операндами можно выполнять следующие арифметические операции, дающие действительный результат:
сложение + , вычитание - , умножение * , деление / .
К величинам действительного типа применимы все операции отношения, дающие булевский результат.
Один из операндов, участвующих в этих операциях, может быть целым.
Итак, чтобы переменную можно было использовать в программе, ее надо предварительно описать, указав ее тип. Пока переменная не описана, обращаться к ней нельзя (хотя в некоторых языках, например в Бейсике и Фортране, считается, что все переменные, не объявленные явно, имеют числовой тип).
Синтаксис команд описания данных
Бейсик |
Паскаль |
Си++ |
DIM имя AS тип |
var имя: тип; |
тип имя; |
Вот примеры описания переменных.
Бейсик: DIM X AS DOUBLE Паскаль: var x: real; var Str: record; PI: integer; S: string; end; Си++: float x; int a[20]; При описании переменных одного типа в Паскале и Си++ их можно указывать через запятую. Паскаль: var xx, z2: integer; Си++: int xx, yy[10], z2;После того как переменная описана, к ней можно обращаться, но она обычно исходно имеет неопределенное значение, поэтому ее надо предварительно инициализировать — присвоить ей начальное значение.
Все переменные, используемые и Паскаль-программе, должны быть перечислены в разделе описания переменных. Этот раздел состоит из предложений описания переменных. Таких предложений может быть несколько, размещаются они между заголовком программы, подпрограммы или модуля и зарезервированным словом begin, открывающим раздел операторов программы, подпрограммы или модуля. Располагаться предложения описания переменных могут вместе (и это одна из составных частей хорошего стиля программирования), но могут и чередоваться с описаниями других объектов: констант, процедур, функций и т. д. Предложение описания переменных имеет вид
var vl,v2... : type_id;Здесь vl, v2,... — список переменных, в котором имена переменных разделяются запятыми, a type_id задает тип переменных из данного списка. Если в данной программе используются переменные разных типов, то в предложении var приводятся списки имен переменных каждого типа:
var v_l_l, v_l_2, ... : type_id_l; v_2_1, v_2_2, ... : type_id_2; … v_n_l, v_n_2, ... : type_id_n; Пример описания переменных: var cows, sheeps : Word; overman : Real; il liana : Extended;
Здесь Word, Real и Extended — названия типов.
В настоящее время в профессиональном программировании принято записывать имена переменных с использованием так называемой венгерской нотации.
Венгерская нотация - это соглашение о наименованиях переменных и функций. Соглашение широко используется при программировании на языках PASCAL, C и в среде WINDOWS.
Венгерская нотация основывается на следующих принципах:
- имена переменных и функций должны содержать префикс, описывающий их тип;
- имена переменных и функций записываются полными словами или словосочетаниями или их сокращениями, но так, чтобы по имени можно было понять назначение переменной или действие, выполняемое функцией.
Префиксы записываются малыми буквами, первая буква каждого слова - заглавная, префиксы и слова записываются либо слитно, либо через символ _ (подчеркивание). Для языка PASCAL могут быть рекомендованы следующие префиксы для скалярных переменных и функций:
by - Byte; sh - Shortint; i - Intege; w - Word; l- Longint; r - Real; si - Single; d - Double; e - Extended; c - Comp; ch - Char; b - Boolean; p - Pointer; x,у - координаты символа или точки на экране.Для величин структурированного типа могут быть использованы следующие префиксы:
a - Array; s - String; re - Record; sz - Stringz; se - Set; f - File; t - Text.Например:
В разделе описаний программы должны быть описаны не только переменные, но и констант. В простейшем случае предложение описания констант имеет вид
Const
v_l = val_l;
v_2 = val_1;
…
v_n = val_n;
Здесь v_l, v_2, ..., v_n — имена констант, а val_i — значения этих констант. Позже мы узнаем, что константы в Паскале бывают двух видов — нетипизированные (как в данном случае) и типизированные. Пример:
const
my_birth_year = 1905;
mass_or_electron = 9.1095e-28;
my_salary = 'invisible';
Для записи арифметических действий используются арифметические операторы. В некоторых языках программирования они считаются не операторами, а операциями, предназначенными для вычисления значения выражения, но не влияющими на другие значения и не сказывающимися на ходе выполнения программы. К основным арифметическим операциям относятся:
+ (сложение),
- (вычитание),
* (умножение) / (деление).
Такая форма записи отвечает общепринятым соглашениям и принята в большинстве языков программирования.
Каждая арифметическая операция имеет свой приоритет. Операции с более высоким приоритетом (умножение и деление) будут выполняться раньше, чем операции с более низким приоритетом (сложение и вычитание). Изменить порядок вычисления выражения можно с помощью круглых скобок.
b*2 + с/3 b*(2 + с) / 3
Скобки допускается вкладывать друг в друга произвольное число раз. При этом использование квадратных или фигурных скобок, как правило, не допускается.
((у+2)*3 + 1) / 2
С помощью арифметических операций формируются арифметические выражения, которые состоят из операций и операндов (переменных и констант). Так, например, выражение
i + 2
состоит из одной операции «+» и двух операндов — переменной i и числовой константы 2.
Каждое выражение имеет значение, которое определяется в момент выполнения оператора, содержащего это выражение. Если на момент вычисления выражения, приведенного выше, в переменной i хранится число 3, то значение этого выражения будет равно (3+2).
При создании программ не обойтись без логических выражений. Они отличаются тем, что результат их вычислений может принимать только одно из двух допустимых значений — true (истина, да, включено) и false (ложь, нет, выключено). Чаще всего значение false ассоциируется с нулем, а значение true — с числом 1 или просто ненулевым значением.
При записи логических выражений используются операции сравнения или логические операции. Операции сравнения сличают значения правого и левого операндов. Результатом сравнения является true, если оно удачно, и false в противном случае.
В таблице 2.4 даны примеры записи операций сравнения для разных языков.
Таблица 2.4
Операция |
Варианты написания |
|
Бейсик, Паскаль |
Си++ |
|
Равно |
= |
== |
Не равно |
<> |
!= |
Меньше |
< |
< |
Меньше или равно |
<= |
<= |
Больше |
> |
> |
Больше или равно |
>= |
>= |
Pi = = 3.14
х > О
a1<>b1
В одном выражении может потребоваться проверка нескольких подобных условий. Например, надо определить, больше ли значение переменной Х чем 0 и меньше ли чем 10. Условия могут быть связаны с помощью логических операций, наиболее активно используемые из которых — это И и ИЛИ. В компьютерной графике также часто применяется так называемое исключающее ИЛИ и операция отрицания НЕ. Для нее требуется только один операнд, указывающийся справа от знака операции. Эта операция просто меняет значение своего операнда на противоположное.
Таблица 2.5
1 операнд | 2 операнд |
И |
ИЛИ |
исключающее ИЛИ |
HE (только первый операнд) |
true |
true |
true |
True |
false |
false |
true |
false |
false |
True |
true |
false |
false |
true |
false |
True |
true |
true |
false |
false |
false |
False |
false |
true |
В следующей таблице приведен синтаксис записи логических операций:
Таблица 2.6
Логическая операция | Бейсик |
Паскаль |
Си++ |
И |
AND |
and |
&& |
или |
OR |
or |
|| |
НЕ |
NOT |
not |
| |
Приоритеты всех логических операций ниже, чем приоритеты операций сравнения, поэтому сравнения всегда выполняются первыми. Алогические операции вычисляются в следующем порядке: сначала НЕ, потом И, потом ИЛИ. При необходимости этот порядок может быть изменен с помощью скобок.
Примеры логических выражений:
х1 >= 1 && х1 <= 10
(R > 3.14) and (R < 3.149)
(Value < Oldvalue) OR (Value <> 0)
Логические операции not, and, or и xor, которые введены в TURBO PASCAL для обеспечения возможности работы с двоичными разрядами (битами) относятся к так называемой битовой или поразрядной арифметике. Операции битовой арифметики применимы только к целым типам.
Так, операция not называется одноместной, она лишь изменяет каждый бит целого числа на обратный.
Операции and, or и xor - двуместные, операнды этих операций - целые величины одинаковой длины. Операции выполняются попарно над всеми двоичными разрядами операндов.
Вторая группа операций - это операции сдвига влево shl и сдвига вправо shr:
I shl N
I shr N.
Эти операции сдвигают двоичную последовательность значения I влево или вправо на N двоичных разрядов. При этом биты, уходящие за пределы разрядной сетки, теряются, а освободившиеся двоичные разряды заполняются нулями. При сдвиге вправо отрицательных значений освободившиеся разряды заполняются единицами.
Строки в языках программирования всегда заключаются в кавычки. В Си++ и Бейсике для этого используются двойные кавычки, в Паскале — одинарные.
"это строка Бейсика или Си++", а 'это строка Паскаля'
Строка может быть пустой — не содержать ни одного символа. Например: " " или ' ' .
Как правило, строки можно сравнивать друг с другом на эквивалентность (равно и не равно). В некоторых языках программирования допускаются также сравнения типа «больше» или «меньше» — при этом происходит последовательное сравнение значений символов (каждый символ представляется в компьютере конкретным числом). Кроме того, часто допускается также операция контенации строк, записываемая с помощью символа « + ». Например:
"123" + "4567" — получится "1234567";
"абв " + "abc " + " эюя" — получится "абв abc эюя"
Тип «строка» |
||
Бейсик |
Паскаль |
Си++ |
STRING |
string |
Базового типа «строка» нет |
Некоторые языки программирования допускают в явном виде работу с указателями — адресами физической памяти. При этом в них имеется специальная операция получения адреса конкретной переменной, что позволяет работать с памятью напрямую, примерно так, как это происходит в языках ассемблера. Такая возможность позволяет добиваться высокой эффективности работы программы, но часто приводит к ошибкам, если указатель вдруг получает неверное значение и при его использовании начинает портиться область памяти, предназначенная совсем для других целей.
Более тесное знакомство с этим мощным средством языков программирования высокого уровня предстоит при изучении темы 12.
Если записать подряд несколько операторов и не указать, где кончается один и начинается другой; то в процессе компиляции возникнет множество проблем с выделением отдельных операторов. Поэтому операторы в Паскале и Си++ отделяются друг от друга точкой с запятой «;» (каждый оператор в этих языках должен заканчиваться таким символом), а в Бейсике — двоеточием «:» или переходом на новую строку.
Часто в программе возникает необходимость выполнить группу операторов (например, в зависимости от какого-либо условия). Такая группа объединяется в блок с помощью специальных скобок начала и конца блока, называемых логическими скобками. В Бейсике явного понятия «блок операторов» нет, в Паскале для этого используются ключевые слова begin и end, а в Си++ — фигурные скобки «{» и «}».
Команды описания переменных могут встречаться в разных местах программы. При этом считается, что объявленные в них переменные являются локальными и их область действия — текущий блок, в котором они описаны. Как только встречается логическая скобка, закрывающая блок (например,«}»), соответствующая переменная перестает существовать, а выделенная для нее память освобождается. Некоторые переменные (глобальные) описываются вне блоков и доступны из любого места программы.
Оператор присваивания позволяет изменять текущее значение переменной. Синтаксис его очень простой. В левой части оператора присваивания указывается имя переменной, значение которой изменяется, а справа — выражение, значение которого будет записано в переменную. При этом старое значение, хранившееся в ней, безвозвратно пропадет.
Сам оператор присваивания записывается знаком «=» в Бейсике и Си++ и комбинацией двух знаков «:=» в Паскале (пробел между ними не допускается).
Например:
Result = 5
В переменную Result запишется число 5. Знак «=» означает именно присваивание, а не сравнение, которое может использоваться только в логических выражениях.
Другой пример:
Х = Х + 1
Сначала вычисляется значение выражения Х+1, и затем оно заносится в переменную X. Допустима и такая запись:
Х = Х = Х.
Прежде всего, выполняется сравнение в правой части (X = X), его значение всегда будет true, и значением переменной X, соответственно, тоже станет true. Для повышения наглядности оператора присваивания в Паскале принята специальная форма его записи:
Х:= Х = Х .
Примеры.
Бейсик:
а23 = а22(12) + 1: b1 = b1 – 1
Паскаль:
а := b*2 + с; d:= (е[8] - f)*2.2;
Си++:
х[5] = у/3.33; у = z[0] - 0.001;
При составлении программы очень полезно комментировать различные участки кода, чтобы потом, обратившись к ним, сразу понять, что конкретно выполняется в том или ином месте программы. Забыть смысл того, что было сделано совсем недавно, можно очень быстро — за несколько недель, а в больших проектах и за несколько дней. Эта проблема становится особенно актуальной, когда группой специалистов разрабатывается объемное приложение, и разобраться в сотнях тысяч строк своего и чужого исходного текста очень сложно.
Языки программирования допускают использование комментариев — частей исходных текстов, выделяемых с помощью специальных обозначений и пропускаемых компилятором при анализе текста программы. Комментарии могут начинаться и заканчиваться особыми символами и охватывать несколько строк кода, а могут записываться только в конце строки — при этом считается, что весь остаток строки является комментарием.
Для обозначения комментариев в одном и том же языке программирования могут использоваться разные символы, поэтому возможно возникновение вложенных комментариев. Допустимость такого вложения задается, как правило, в настройках компилятора.
Таблица 2.7
Синтаксис комментария |
|||
Вид комментария |
Бейсик |
Паскаль |
Си++ |
Однострочный комментарий |
REM или ' |
// |
// |
Многострочный комментарий |
нет |
{} или (* *) |
/* */ |
Х = 5 'комментарий до конца строки
Х := 5; // комментарий до конца строки
/*
это комментарий языка Си++
*/
{это комментарий языка Паскаль
(* а это вложенный комментарий *)