Переменные и типы данных

В разделе 5.1 говорилось о том, что языки программирования высокого уровня позволяют обращаться к ячейкам памяти предпочтительно через описательные имена, а не через числовые адреса. Такие имена называются переменными (variable), тем самым подчеркивается тот факт, что при изменении значения, хранящегося в ячейке памяти, изменяется и значение, присвоенное переменной. В рассматриваемых нами языках все переменные, которые будут использоваться в программе, должны быть предварительно определены с помощью операторов описания. В этих же операторах необходимо описать типы данных, которые будут храниться в ячейках, связанных с переменными.

Понятие тип данных (data type) включает в себя и способ кодировки данных, и операции, которые можно выполнять над этими данными. Например, к типу данных integer (целые числа) относятся числовые данные, состоящие из целых чисел, которые хранятся в двоичном дополнительном коде. Над целыми числами можно выполнять обычные арифметические операции и операции сравнения. К типу данных real, или вещественные числа (в некоторых языках он называется float), относятся числовые данные, которые содержат действительные числа, представленные в формате с плавающей запятой. Над данными типа real можно выполнять те же операции, что и над целыми числами. Однако обратите внимание на то, что при сложении двух целых чисел и при сложении двух вещественных чисел выполняются разные действия.

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

int WeightLimit:

которое означает: «Имя WeightLimit будет использоваться дальше в программе по отношению к ячейке памяти, содержащей значение, представленное в двоичном дополнительном коде». В одном выражении можно объявить тип нескольких переменных. Например, выражение

int Height. Width;

объявляет обе переменные, Height и Width, как переменные типа integer. Кроме того, многие языки позволяют при описании переменной задавать ее первоначальное значение1. Таким образом, выражение

int WeightLimit = 100;

не только объявляет переменную WeightLimit переменной типа integer, но гакже присваивает ей начальное значение 100.

Другими распространенными типами данных являются character (символьный тип) и Boolean (логический тип). К символьному типу данных character относятся данные, состоящие из символов, хранящихся в кодировке ASCII или Unicode. Над такими данными можно выполнять операцию сравнения, то есть определять, находится ли один символ перед другим в алфавитном порядке, проверку, является ли цепочка символов подцепочкой другой, а также операцию конкатенации, то есть то есть добавления одной цепочки символов в конец другой.

К логическому типу данных Bool ean относятся элементы данных, которые могут принимать только два значения — true (истина) или false (ложь). К таким переменным можно применять операцию запроса, является текущее значение переменной истиной или ложью. Например, если переменная EndOfList является переменной логического типа, то можно использовать такое выражение

if (EndOfList) then (...) else (...).

К другим типам данных, которые еще пока не являются примитивами в языках программирования, относятся изображения, аудио-, видео- и гипертекст. Однако такие типы, как GIF, JPEG и HTML, могут в ближайшем будущем стать такими же обычными, как integer и real. Язык Java, который содержит инструменты для работы со многими такими типами данных, является шагом в этом направлении.

Пример того, как можно описать одни и те же переменные в разных языках программирования, представлен в табл. 5.1. (Переменные Length и Width являются переменными вещественного типа, переменные Price, Tax и Total — целочисленные переменные, а переменная Symbol является переменной символьного типа.) Обратите внимание на то, что языки больше различаются по форме, чем по содержанию. В разделе 5.4 мы рассмотрим, как транслирующая программа использует сведения, собранные из таких декларативных выражений, чтобы преобразовать программу, написанную на языке высокого уровня, в машинные команды. А пока обратите внимание на то, что такую информацию можно использовать для поиска ошибок. Например, выражение, которое требует сложения двух переменных символьного типа, по всей видимости, содержит ошибку.

Таблица 5.1. Описание переменных в разных языках программирования

Описание переменных в языке Pascal var

Lehgth, Width: real; Price, Tax, Total: integer; ____________________________________________Symbol:____________char;___________________

Описание переменных в языках С, C++, С# float Length, Width; и Java int Price. Tax, Total: ____________________________________________char Symbol;______________________________

Описание переменных в языке FORTRAN REAL Length, Width

IMTEGER Price. Tax. Total __________________________________________________CHARACTER Symbol_______________________________

Структуры данных

Переменные в программе могут быть не только данными простых типов, но также структурами данных (data structure), то есть данными, упорядоченными каким-либо образом. Например, текст обычно рассматривается как длинная цепочка символов, а учетные записи продаж можно представить в виде таблицы, в которой в строке записываются продажи, сделанные определенным сотрудником, а в столбце — продажи, сделанные в определенный день.

Наиболее распространенной структурой данных является однородный массив (homogeneous array). Однородный массив представляет собой набор значений одного типа, например одномерный список, двумерную таблицу или таблицу с большим количеством измерений. В большинстве языков программирования для того, чтобы описать массив, нужно задать количество измерений, а также число элементов в каждом измерении. Например, структура, описанная выражением в языке С int Scores [2] [9];

означает: «Переменная Scores будет использоваться в программе для обозначения двумерного массива целых чисел, состоящего из двух строк и девяти столбцов» (рис. 5.5). То же самое выражение на языке FORTRAN будет выглядеть следующим образом:

INTEGER Scores (2.9).

После описания массива к нему можно обращаться по заданному имени. А к отдельным элементам массива можно обращаться с помощью целых чисел, которые называются индексами (indices). Они определяют строку и ряд, в котором находится элемент массива. Однако диапазон индексов меняется от языка к языку. Например, в языке С (и его производных C++, Java и С#) индексы начинаются с 0. То есть элемент, находящийся во второй строке и четвертом столбце массива Scores, можно обозначить с помощью выражения Scores [1] [3], а элемент, расположенный в первой строке и первом столбце, будет обозначаться как Scores [0] [0]. Напротив, в языке FORTRAN индексы начинаются с 1, поэтому элемент, расположенный во второй строке и четвертом столбце, будет обозначаться как Scores (2,4) (см. рис. 5.5).

Некоторые языки программирования предоставляют программисту свободу в выборе интервала индексов для однородного массива. Например, выражение Scores: array [3..4. 12..20] of integer:

Таблица 5.1. Описание переменных в разных языках программирования
Описание переменных в языке Pascal var Lehgth, Width: Price, Tax, Total Symbol: real;: integer; char;
Описание переменных в языках С, C++, С# и Java float Length, Width; int Price. Tax, Total: char Symbol:
Описание переменных в языке FORTRAN REAL Length, INTEGER Price. CHARACTER Symbol Width Tax. Total

в языке Pascal описывает такой же двумерный массив целых чисел Scores, как и приведенный выше, за исключением того, что строки здесь определены значениями 3 и 4, а столбцы пронумерованы от 12 до 20. Поэтому элемент, расположенный во втором ряду и четвертом столбце, будет обозначаться выражением Scores [4,15].

В отличие от однородного массива, в котором элементы данных относятся к одному типу, неоднородный массив (heterogeneous array) может содержать данные разных типов. Например, совокупность данных о сотруднике компании может состоять из элемента символьного типа Name, элемента целочисленного типа Аде и элемента вещественного типа Ski 11 Rating. В языках Pascal и С (рис. 5.6) такой тип массива называется соответственно записью (record) и структурой (structure).

Описание неоднородного массива в Pascal

var

Employee: record

Name: packed array [1..8] of char; Age: integer; SkillRating: real end

Описание неоднородного массива в С

struct

{ char Name [8];

int Age:

float SkillRating; } Employee:

К компоненту неоднородного массива обычно обращаются по имени массива, после которого ставится точка и затем указывается имя этого компонента. Например, к компоненту Age массива Employee (см. рис. 5.6) можно обратиться с помощью выражения Employee.Age.

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

Константы и литералы

Иногда в программе используются фиксированные, заранее заданные значения. Например, программа, управляющая воздушным движением определенного аэропорта, может содержать различные ссылки на положение этого аэропорта относительно уровня моря. В процессе написания программы это значение, скажем, 645 футов, можно каждый раз записывать числом. Такая явная запись значения называется литералом (literal). В результате использования литералов получаются такие выражения, как

EffectiveAlt <- Altimeter - 645

где EffectiveAlt и Altimeter — переменные, а 645 — литерал.

Однако использование литералов не очень удобно, поскольку иногда трудно понять значение выражения, в которое они включены. Как, например, можно узнать из предыдущего выражения, что означает число 645? Кроме того, использование литералов может усложнить изменение программы, если оно потребуется. Если с этой программой работать в другом аэропорту, то все ссылки на положение аэропорта относительно уровня моря нужно изменить. Если используется литерал 645, то нужно просмотреть всю программу и изменить каждое выражение, в котором он встречается. Трудности могут возникнуть в том случае, когда литерал 645 используется также для обозначения какого-либо другого свойства. Как тогда узнать, какое из них нужно поменять?

Для того чтобы избежать этих трудностей, в языках программирования существует возможность присваивать постоянным значениям описательные имена. Такие имена называются константами (constant). Например, описательный оператор языка Ada

AirportAlt constant Integer:= 645:

присваивает имени Ai rportAl t фиксированное значение 645 целочисленного типа. То же самое выражение можно записать на Java:

final int AirportAlt = 645;

а на C++ и С# оно будет иметь следующий вид:

const AirportAlt = 645.

После такого выражения имя AirportAlt можно использовать вместо литерала 645. Используя эту константу в нашем псевдокоде, выражение

EffectiveAlt <- Alireter - 645

можно переписать как

EffectiveAlt <- Alimeter - AirportAlt.

Нетрудно заметить, что последнее выражение лучше отражает смысл утверждения. Кроме того, если программу, содержащую такие константы, использовать в другом аэропорту, который находится на высоте 267 футов над уровнем моря, то все, что нужно сделать, это изменить параметры одного оператора описания.


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: