Архитектура Аудит Военная наука Иностранные языки Медицина Металлургия Метрология
Образование Политология Производство Психология Стандартизация Технологии


Имена объектов программы должны быть осмысленными.



Пример.

tip razmer adres

Hе надо!

xx aa a1 a2

В настоящее время во всем мире приняты 2 системы записи (нотации) имен: " паскалевская" и " венгерская". Обе рекомендуют использовать имена, состоящие, в общем случае, из нескольких слов. В " паскалевской" нотации каждое слово начинают с прописной буквы.

Пример.

BegKm EndKm FieldName

В " венгерской" нотации перед именем записывается тип объекта программы.

Пример.

intBegKm intEndKm charFieldName

Не используйте в программе сходные имена!

Пример.

value values

ax1 axi

k K

Если имя содержит цифры, записывайте их в конце.

Пример.

fund1 Tab15

Имя не должно совпадать с ключевым словом или с именем библиотечной функции.

В языках Basic и С ключевые слова зарезервированы, т.е. при подобном совпадении транслятор выдает ошибку. Однако в некоторых языках допустимы такие конструкции.

Пример. Язык PL/1.

if if = then then

then = else;

Else

else = if;

Язык и приемы программирования

Активно используйте удобные и понятные особенности языка.

Пример.

a=b=0; k++; x+=c; //Многократное присваивание – это удобно!

Basicà x=5: y=x^3-2 '2-3 связанные короткие инструкции в 1 строку

Изучайте и используйте библиотечные функции. Малоупотребительные комментируйте.

Пример.

// pow(x, n) – возведение x в степень n

3. Не применяйте трюки!

Пример. Формирование единичной матрицы.

for (k=0; k< n; k++){

for (m=0; m< n; m++){

x[k][m]=((k+1)/(m+1))*((m+1)/(k+1)); // Это трюк!

}

}

То же самое можно записать так.

for (k=0; k< n; k++){

for (m=0; m< n; m++){

x[k][m]=0;

}

x[k][k]=1;

}

4. Не игнорируйте предупреждения и старайтесь их ликвидировать!

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

Conversion may lose signicant digits à При преобразовании могут быть потеряны значащие цифры. Возникает, например, при попытке присваивания short = long или Integer = Long ( Basic ).

Parameter 'doc' is never used à Параметр 'doc' никогда не используется. Чаще всего возникает после модификации выполняемых инструкций программы, когда необходимость в параметре doc отпала, а в объявлении или в списке параметров процедуры он сохранился.

Избегайте промежуточных переменных. Формулы следует записывать в том же виде, как это принято в математике.

Пример.

y=2*(a+b) / sqrt((a+b)*(a+b)+(c+d)*(c+d));

Не изменяйте значение параметра цикла внутри тела цикла.

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

Избегайте инструкций перехода.

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

Не используйте помеченные инструкции, на которые нет ссылок.

Единственный смысл такого применения меток – это дополнительное комментирование. Зачем тогда комментарии языка?

Объявляйте все переменные явно.

Явное объявление, кроме своей основной функции определения типа объекта программы, позволяет выявить 1 весьма распространенный вид ошибок – описки. Применение подобных имен в тексте вызовет ошибку или предупреждение при трансляции.

Не используйте одни и те же переменные для различных целей.

При последующей модификации одного фрагмента программы такие переменные могут вызвать ошибку в другом фрагменте.

Не забывайте, что данные с плавающей точкой есть приближенные представления десятичных значений.

Для них с осторожностью надо применять операции равно и не равно.

Пример. Цикл с вещественным параметром.

For x=0 To 2 Step 0.05

........................

Next x

При x=2 проход по циклу может не выполниться. Надо записывать так:

For x=0 To 2.02 Step 0.05

........................

Next x

Используйте исчерпывающие проверки.

Если переменная должна принимать значения 1|2|3, не следует полагать, что ее значение равно 3, если оно не равно 1 и не равно 2, т.к. возможны ошибки.

Стиль в языках С и Basic

По оценке автора:

ОВ – весьма важная рекомендация;

В – рекомендация средней важности;

МВ – рекомендация относительно малой важности.

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

1. (В) Имена. Использовать " паскалевскую" или " венгерскую" нотации.

2. (В) Описатели. Если постановка задачи не требует повышенной точности представления, использовать для данных с плавающей точкой типы float ( C ) и Single ( Basic ).

3. Литералы.

(МВ) Для трансляторов языка C, в которых не предусмотрены логические данные, разумно ввести в программу логические литералы.

# define TRUE 1

# define FALSE 0

Не следует забывать, что логические данные в программе на языке Basic занимают в памяти 2 байта, значения хранятся в виде True (-1), False (0), а на языке C они занимают в памяти 1 байт и хранятся в виде true (1), false (0).

(В) Старайтесь избегать в тексте программы литералов, заменяйте их символическими константами с помощью директивы #define (язык C ) или #const (язык Basic ).

4. (В) Массивы.

Для языка C следует отметить такие особенности.

Если возможно изменение размеров массивов, определяйте их размеры с помощью директивы #define.

Пример.

#define SIZE 50

float Matrix[SIZE][SIZE];

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

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

Пример.

Dim Matrix(, ) As Single

Затем в том месте процедуры, где требуется определить границы каждого измерения, применяют инструкцию ReDim.

Пример.

ReDim Matrix(10, 10)′ 10-верхняя граница индекса

′ Память под матрицу 11х11

Такая инструкция в теле процедуры может использоваться многократно. Более подробно синтаксис и область применения инструкции ReDim будет изложена разделе 10.6. «Динамические массивы».

Минимальное значение индекса также всегда равно 0, поэтому не следует применять разрешенную правилами инструкцию вида: < имя массива> (< нижняя граница> to < верхняя граница> ). Это приводит к избыточному выделению памяти.

5. (ОВ) В языке C необходимо помнить об особенностях операторов деления / и остатка % при работе с целыми операндами. При делении целого на целое результат всегда целый. Оператор % используйте только для целых операндов.

6. (В) Для логических операторов & & и || в языке C вычисление выражения прекращается, как только результат определен, а для аналогичных операторов And и Or в языке Basic проверяются оба операнда.

Пример.

Выражение i< 100 & & x[ i ]< 0 при i=100 в языке C примет значение false и выполнение программы продолжится, тогда как в языке Basic вычисление выражения i< 100 А nd x( i )< 0 при тех же условиях вызовет ошибку: Subscript out of range (Индекс вне диапазона), поскольку элемента массива x(100) не существует. В подобном случае следует использовать операторы AndAlso и OrElse.

7. (ОВ) В языке C при использовании библиотечных функций не забудьте включить файл прототипов.

Пример.

#include < stdio.h>

#include < math.h>

8.(В) Не забывайте об удобных возможностях языка С: многократном присваивании, операторах: ++ -- < знак> = (для Basic тоже).

9. Ввод-вывод:

C (ОВ):

- при вводе информации функцией scanf в списке данных необходимо использовать оператор нахождения адреса &;

- не забывайте заканчивать ввод данных инструкции scanf клавишей Enter (закрывает буфер ввода);

- не забывайте заканчивать управляющую строку инструкции printf символом '\n' (перевод на новую строку);

- при неизвестном диапазоне выводимых значений данных с плавающей точкой используйте спецификацию g.

Basic (В)

Так как в отличие от языка С, здесь используется методы, входящие в состав класса, то для сокращения объема кода разумно использовать инструкцию Imports System. < имя класса>. Это позволит не записывать имя класса при обращении к методам этого класса.

Пример.

Imports System.Math

Imports System.Console

…………………………….

y=Cos(x)+Sin(x)

WriteLine(" y={0: g5}" , y)

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

Вопросы для самопроверки

1. Как разумно размещать инструкции текста программы?

2. Какую роль играют отступы при размещении вложенных инструкций?

3. В чем суть " венгерской" нотации имен?

4. На что, вероятно, указывает предупреждение при трансляции?

5. В чем различие в применении операторов " И" и " ИЛИ" в языках C и Basic?

6. Чем отличается действие оператора деления / в языках C и Basic?

Контрольные вопросы

1. В каких местах нужно осуществлять перенос инструкции, если она не входит в строку?

2. Перечислите типы комментариев к программе.

3. Почему нежелательно использовать в программе схожие имена?

4. Зачем нужно явно объявлять все объекты программы?

5. Почему следует избегать инструкций перехода?

6. В чем преимущество работы с массивами в языке Basic?

ДАННЫЕ. ДОПОЛНЕНИЕ

Материал данного раздела содержит информацию о типах и совокупностях данных, специфических для конкретного языка программирования, поэтому ниже рядом с названием раздела в скобках будет указываться принадлежность описываемой конструкции к языку: C++ и B Basic.

Перечислимый тип

10.1.1. Тип enum (C++)

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

enum < имя_типа> {< имя_элемента> [=< значение> ],

[< имя_элемента> [=< значение> ]]...};

Пример.

enum spectr{RED, ORANGE, YELLOW, GREEN, BLUE, VIOLET};

Затем можно определять переменные этого типа:

spectr color1, color2;

Ключевое слово enum является сокращением от enumeration – перечисление.

Запись из примера эквивалентна введению символических констант вида:

# define RED 0

# define ORANGE 1

# define YELLOW 2

# define GREEN 3

# define BLUE 4

# define VIOLET 5

Переменные типа spectr могут принимать только указанные значения. При попытке присваивания им другого значения выдается ошибка.

Пример.

color1=GREEN; // Допустимо

color2=WHITE; // Ошибка!

Если при объявлении типа символическим константам из списка не задается значений, то первая из них по умолчанию получает значение 0, последующие на 1 больше. Если какой-либо из констант задается значение, а последующим нет, то они получают следующее по порядку целое значение.

Пример.

enum RussianCop{five=5, ten=10, fifty=50};

enum RussianRoub{One=1, Two, Five=5, Ten=10, Fifty=50, Hundred=100, FiveHundred=500, Thousand=1000, FiveThousand=5000};

enum mark{BAD=2, MIDDLE, GOOD, FINE};

Фактически разумными при работе с данными перечислимых типов являются только следующие операторы: присваиваниеà color1=VIOLET; и сравнениеà color1==color2.

Заметим, что введение такого типа данных служит прежде всего для большей понятности и удобочитаемости текста программы.

10.1.2. Тип enum (B)

Практически аналогичен такому же типу языка C++.

Формат объявления типа:

Enum < имя_типа>

< имя_элемента> [=< значение> ]

[< имя_элемента> [=< значение> ] ]

.......................................................

End Enum

Пример.

Enum spectr

Red

Orange

Yellow

Green

Blue

Violet

End Enum

Объявление переменных имеет вид:

Dim color1, color2 As spectr

Правила объявления и использования переменных этого типа полностью совпадают с правилами языка C++. Имеются только 2 отличия:

- значения переменных и перечисляемых констант относятся к типу long;

- при присвоении переменной значения не из списка констант ошибки не возникает.

10.2. Тип decimal (B)

Данные этого типа занимают в памяти 16 байтов, 12 из которых отводится для целого значения со знаком. Остальные отводятся для хранения масштабирующего коэффициента, определяющего во внешнем представлении число знаков после десятичной точки. Масштабирование выполняется при задании переменной значения.

Примерный диапазон представления (по абсолютной величине):

1e-28 – 7.93e+28.

Литералы данного типа определяются добавлением в конец значения символа d.

Значение по умолчанию (как для всех числовых типов) равно 0.

Пример объявления переменных.

Dim sum1, TotalSum as Decimal

………………………………………

sum1 = 12345.678905e-15D

После завершения ввода текста среда масштабирует введенное значение и преобразует его.

sum1 = 0.000000000012345678905D

Эти данные полезны при денежных расчетах и вычислениях с фиксированной точкой с заданной точностью и дают возможность задавать максимальное количество значащих цифр.

Замечание. До версии Visual Basic.NET (2008) в языке существовал тип данных Currency, предназначенный для проведения денежных расчетов, который относился к десятичным данным с фиксированной точкой (4 знака после точки). В связи с тем, что платформа Visual Studio является многоязыковой средой разработки (языки C++, VB, C#, F# ) и требует одинаковые типы данных для них, указанный тип, начиная с версии VS2008, был заменен на тип данных Decimal.

10.3. Тип date (B)

Данные этого типа в памяти представляются специальным форматом, точно знать который нет необходимости. Каждый элемент занимает в памяти 8 байтов. Диапазон представления дат от 1 января 0001 года до 31 декабря 9999 года, времени – от 0: 00: 00 до 23: 59: 59.

Литералы данного типа заключаются между символами #. Они могут записываться в различных форматах, однако после окончания ввода среда преобразует введенный формат даты/времени в формат, принятый в USA: m/d/yyyy h: mm: ss {AM|PM}, где m - № месяца (1 или 2 цифры в зависимости от значения), d - № дня в месяце (аналогично), yyyy – год, h – час (1 или 2 цифры), mm – минуты, ss – секунды, AM (ante meridiem – до полудня), PM (post meridiem – после полудня) – указатели 12-часовой шкалы.

Пример.

#01 Jan2001# à #1/1/2001#

#13: 03: 03# à #1: 03: 03 PM#

#13/11/2001 5: 54: 56# à #11/13/2001 5: 54: 56 AM#

Подобное преобразование может привести к ошибке. Например, запись вида #9/3/2001# будет интерпретироваться как: 3 сентября 2001 года, тогда как, возможно, имелось в виду 9 марта 2001 года (принятый в России краткий формат даты). Поэтому разумно записывать литералы даты/времени как строки. При этом преобразования формата в среде не будет.

Пример.

" 09.03.2001 18: 34: 30" à 9 марта 2001 года 6 часов 34 минут 30 секунд вечера

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

Пример объявления переменных.

Dim BirthDay A s Date

С данными этого типа можно манипулировать непосредственно. Например, разницу в датах можно получить так:

Dim day1, day2 A s Date, day3 A s Integer

day1 = #3/9/1999#

day2 = #3/10/2001#

day3 = day2 - day1

Получим 732.

Замечание. Visual Studio.NET различных версий является многоязыковой средой разработки, которую часто называют платформой.NET Framework или Dot NET ( dot – точка). Она использует типы данных, общие для всех языков. В конкретных языках для обозначения типов данных используют псевдонимы для этих общих типов. Например, тип Short соответствует Int16, тип Integer Int32. Для типа Date таким общим типом является DateTime. Тип DateTime предоставляет пользователю различные методы (функции) для обработки данных, содержащих даты и/или время. При обращении к ним перед именем метода должен стоять префикс Date или имя переменной типа Date, для которой выполняется манипуляция.

Ниже приводятся наиболее популярные функции, методы и свойства, которые разделены на 3 группы по виду обращения.

Обращение без префикса.

DateString – возвращает системную дату в формате mm-dd-yyyy.

TimeString – возвращает системное время в виде hh: mm: ss.

Now – возвращает системные дату и время в формате установок ОС.

DateAdd (интервал-литерал String , число, дата) – возвращает дату, отстоящую от дата на число интервалов. Возможные значения аргумента интервал:

- yyyy – год,

- q – квартал,

- m – месяц,

- ww – неделя,

- d – день,

- h – час,

- n – минута,

- s – секунда.

Пример.

DateAdd(" m", 1, #1/31/2000#) à #02/29/2000#

DateDiff (интервал, дата1, дата2) – возвращает число интервалов между дата2 и дата1. Если дата1 > дата2, возвращается число < 0. Функция имеет 2 необязательных аргумента: первый день недели и первая неделя года и значение интервала = " w – день недели. Употребление этих значений изучить самостоятельно.

Пример.

DateDiff(" d", #3/9/2000#, #3/10/2001#) à 366

DatePart (интервал, дата) – возвращает заданную интервалом часть дата. Функция также имеет 2 необязательных аргумента: первый день недели и первая неделя года. По умолчанию первым днем недели считается Воскресенье. В примере показано как с помощью символической константы сделать первым днем Понедельник. Аналогичные константы есть и для других дней недели.

Пример.

DatePart(" yyyy", #3/9/2015#, vbMonday) à 2015 ' vbMonday=2

DatePart(" q", #3/9/2015#, vbMonday) à 1

DatePart(" m", #3/9/2015#, vbMonday) à 3

DatePart(" d", #3/9/2015#, vbMonday) à 9

DatePart(" ww", #3/9/2015#, vbMonday) à 11

DatePart(" w", #3/9/2015#, vbMonday) à 1 ‘w – день недели

DateSerial (год, месяц, день) – возвращает значение типа Date.

Пример.

DateSerial(2014, 2, 26) à 26.02.2014 0: 00: 00

Day (дата) – возвращает день месяца.

Weekday (дата[, 1-й день недели]) – возвращает порядковый № дня недели.

Month (дата) – возвращает № месяца.

Year (дата) – возвращает год.

Today – возвращает системную дату.

Timer – возвращает значение типа Double, показывающее количество секунд, прошедших с начала суток.

DateString – возвращает системную дату в виде строки.

Пример.

Day(#3/9/2015#) à 9

Weekday(#3/9/2015#, vbMonday) à 1

Month(#3/9/2015#) à 3

Year(#3/9/2015#) à 2015

Hour (время) – возвращает целое от 0 до 23 (час аргумента).

Minute (время) – возвращает минуты (0 – 59).

Second (время) – возвращает секунды (0 – 59).

Пример.

Hour(#6: 34: 30 PM#) à 18

Minute(#6: 34: 30 PM#) à 34

Second(#6: 34: 30 PM#) à 30


Обращение с префиксом имя переменной.

Используется для преобразования значения дата/время в строку.

Data1.ToString – преобразует значение типа Date в строку.

Data1.ToShortDateString – то же в короткий формат даты.

Data1.ToLongDateString - то же в длинный формат даты.

Пример.

Dim data1 As Date =" 26.2.2014"

data1. ToString à 26.02.2014 0: 00: 00

data1. ToShortDateString à 26.02.2014

data1. ToLongDateString à 26 февраля 2014 г.

Обращение с префиксом Date .

Date.IsLeapYear (год) – возвращает True, если год високосный, False, если нет.

Date.DaysInMonth (год, месяц) – возвращает число дней в месяце заданного года.

10.4. Тип void (С)

Так называемый " пустой" тип. Служит для согласования синтаксиса функций, не возвращающих значений или не имеющих аргументов.

Пример.

void putmsg( ){

printf(" Hello, world! \n" );

} /* End putmsg */

Этот тип также используется для формирования " универсальных" указателей void *, о которых пойдет речь в другом разделе.

10.5. Подмассивы (сечения) (C)

В языке С можно рассматривать многомерный массив как одномерный, элементами которого являются массивы на 1 меньшей размерности.

Пример.

float sales[3][4][5];

Такой объект можно трактовать как массив с плавающей точкой, состоящий из 3 элементов, каждый из которых является двумерным массивом размером 4*5.

Допустимы следующие обращения к содержимому этого массива:

sales – массив целиком,

sales[ i ] – к i -му подмассиву 4*5,

sales[ i ][ j ] – к элементу с индексами i и j: массив из 5 элементов,

sales[ i ][ j ][ k ] – скалярная величина: собственно элемент массива sales.

Использование сечений иногда весьма удобно, особенно при обращении к процедуре.

 


 

Пример. Найти индексы максимальных элементов каждой строки матрицы.

#define M 30

#define N 30

int main( ){

float a[M][N]; int s[M], ind( int, float [ ]);

..............

for (i=0; i< m; i++){

s[ i ]=ind(n, a[ i ]); // Аргументом функции ind является i -я строка

}

..............

}//End main

int ind( int n, float x[ ]){// Параметр есть одномерный массив длиной в

// строку

int i, k; float y;

k=0; y=x[0];

for (i=1; i< n; i++){

if (y< x[ i ]){

y=x[ i ]; k=i;

}

}

return k;

} //End ind

10.6. Динамические массивы (B)

Иногда возникает необходимость работы с массивами, размеры которых могут меняться в процессе ее выполнения. В этом случае в программах на языке Basic используются динамические массивы.

Такой массив объявляется обычным образом, но без указания границ индексов, но с указанием размерности, которая, как и тип элементов, не может быть изменена.

Пример.

Dim DinArray(, ) As Single

Задание первоначальных границ индексов такого массива производится во время выполнения программы инструкцией вида:

ReDim [ Preserve ] < имя массива> (< выражение> [, < выражение> ]...)

Инструкция Redim в отличие от инструкции Dim является выполняемой. Последующие инструкции могут изменить границы индексов.

Пример.

Redim DinArray(m-1, n-1)

................................

ReDim DinArray(m, n)

Замечание. Напомним, что в Visual Basic.NET, начиная с версии 2008, нижняя граница измерений массивов всегда равна 0, поэтому имеет смысл изменять только их верхние границы (максимальный индекс).

При выполнении инструкции ReDim все значения элементов, которые были заданы ранее, теряются. При этом числовые значения заменяется нулями, строки – пустыми строками (" " ). Однако, имеется возможность сохранить " старые" значения элементов массива. Для этого в инструкции ReDim необходимо употребить ключевое слово Preserve (сохранить). При использовании опции Preserve можно изменять только верхнюю границу последнего измерения.

Пример.

ReDim Preserve DinArray(m-1, n)

Пример. Дан целый массив ai, i=1…m. Сформировать массив b из элементов массива a без повторяющихся значений.

b(0)=a(0): n=1

For i = 1 To m - 1

For j = 0 To n - 1

If a(i) = b(j) Then Exit For

Next

If j = n Then ' Включаем в b

n += 1

ReDim Preserve b(n - 1)

b(n - 1) = a(i)

End If

Next

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

UBound (< имя_массива> [, < № измерения> ]) – верхняя граница. По умолчанию № измерения равен 1.

Пример. Увеличить на 1 границы массива DinArray.

ReDim DinArray(Ubound(DinArray)+1, Ubound(DinArray, 2)+1)

Структуры и объединения

Структуры

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

Пример. Структура " Работник" ( Worker ):

- таб. номер;

- фамилия и.о.;

- должность;

- сумма.

Формат структуры:

struct [< тип структуры> ]{

< список описаний элементов>

}[< список объектов> ];

Пример.

struct { // Сведения о звезде

long nom_GC; // Номер по каталогу GC

float mv; // Блеск (звездная величина)

char spectr[5]; // Спектр. класс

double alfa; // Прямое восхождение

double delta; // Склонение

double mu_alfa; // Собственное движение по alfa

double mu_delta; // ------------------- ------------- по delta

char rem[15]; // Особенности (примечания)

} star;

Структура star содержит сведения об одной звезде. Это определение, т.е. под нее выделяется память, объем которой определяется суммарным размером всех элементов, входящих в структуру. В нашем примере он составляет 56 байтов.

Пример. Определение нескольких структур одного строения.

struct {

.......

} ref_star, // Опорная звезда

view_star; // Наблюдаемая звезда

Часто применяется описание (не определение! ) типа структуры с последующим его использованием при объявлении переменных данного типа. Фактически это способ введения типа данных пользователя в отличие от предопределенных типов языка C++. Тип часто называют ярлыком или меткой структуры. В большинстве случаев без него можно обойтись, однако он необходим при описании рекурсивных структур, которые излагаются ниже в данном разделе.

Пример. Описание типа star.

struct star{

............

};

Определение переменных данного типа:

star ref_star, // Опорная звезда

view_star; // Наблюдаемая звезда

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

Примеры.

struct star{

long nom_GC;

float mv;

char spectr[5];

struct { // Подструктура

double alfa;

double delta;

} koord; // Координаты

struct { // Подструктура

double alfa;

double delta;

} move; // Собственное движение

char rem[15];

};

struct data{ // Дата

int day; // День месяца

int month; // Номер месяца

int year; // Год

char month_name[4]; // Название месяца

};

struct form{ // Анкета

char name[25]; // Фамилия И.О.

char address[30]; // Адрес

char post[20]; // Должность

data birth_date; // Дата рождения

data work_date; // Дата поступления на работу

};

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

Пример.

ref_star.koord.delta

form.birth_date.year

Допустимы массивы структур.

Пример.

struct { /* Сведения о погоде за год */

struct {

double max, min, mid;

} temperature;

struct {

double max, min, mid;

} humidity;

struct {

double max, min, mid;

} pressure;

short number_of_observations;

} weather[12];

В языке Basic для объявления структур используют ключевое слово Structure.

Формат объявления

Dim Structure < тип>

< список элементов>

End Structure

Это описание нового типа данных. Для определения (выделения памяти) переменных этого типа необходимо объявление вида

< тип> < переменная> [, < переменная> ]…

Пример. Объявление типа

Dim Structure star ′ Сведения о звезде

nom_GC As Long ′ Номер по каталогу GC

mv As Single ′ Блеск (звездная величина)

spectr As String ′ Спектр. класс

alfa As Double ′ Прямое восхождение

delta As Double ′ Склонение

mu_alfa As Double ′ Собственное движение по alfa

mu_delta As Double ′ ------------------- ------------- по delta

rem As String ′ Особенности (примечания)

End Structure

Объявление переменных

Dim view_star, ref_star As star

Обращение к элементам структуры выполняется по тем же правилам, что в языке C++.

Пример.

view_star.mu_alfa

ref_star.rem

Все правила языка C применимы и к языку Basic.

10.7.2. Рекурсивные структуры (С++)

Рекурсией, в общем случае, можно назвать правило, позволяющее определить некоторый объект с помощью другого объекта той же структуры. Наиболее распространены рекурсивные функции, простейшим примером которых является формула вычисления факториала: n! =n*(n-1)!

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


 

Пример.

struct node{

int data;

node *next;

};

Здесь в состав структуры включают указатель на структуру того же типа. Такие структуры называют рекурсивными. Их применение будет рассмотрено в курсе " Структуры данных".

Поля битов (С)

До сих пор минимальными адресуемыми элементами программы являлись объекты размером в 1 байт. Примерами таких объектов являлись данные типа char в языке C и типа Byte в языке Basic. Однако байт содержит 8 битов (двоичных цифр). Язык C позволяет манипулировать с отдельными битами информации. Такая необходимость возникает, в основном, при программировании аппаратуры, входящей в состав ПК, или программно-аппаратного комплекса. Средством реализации такой возможности является особый вид структуры, имеющий в качестве элементов так называемые поля битов.

Записываются такие структуры следующим образом:

struct {

unsigned [< имя> ]: < число битов>;

..........................

}

Пример. Формат регистра состояния ГД RX211.

struct {

unsigned error: 1;

unsigned initialize: 1;

unsigned addr: 2;

unsigned rx02: 1;

unsigned : 2; /* Hе используются */

unsigned density: 1;

unsigned trreg: 1;

unsigned enable: 1;

unsigned done: 1;

unsigned select: 1;

unsigned funct: 3;

unsigned go: 1;

}save_211;

Поле битов без имени нулевой длины вызывает выравнивание последующих полей на границу объявленного типа данных, т.е они располагаются с адреса, кратного 32.

Объединения (смеси) (С)

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

union [< тип> ]{

описание элемента 1;

описание элемента 2;

...................;

описание элемента n;

}[< список> ];

Пример.

union {

floa t radius; // Окружность

float side[2]; // Прямоугольник

float triangle[3]; // Треугольник

float point[2]; // Точка

}GeomFig;

В каждый момент времени в памяти, отведенной объединению, может находиться только один элемент, т.е. память используется элементами поочередно. Размер отводимой памяти определяется размером наиболее " длинного" элемента. В примере это " треугольник" – 12 байтов.

Заметим, что обобщением понятия объединения является тип данных Object в языке Basic.

Переменные структуры

Переменной называют структуру, в состав которой входит хотя бы 1 смесь.

Общая схема построения такой структуры следующая:

struct {

общие компоненты,

признак активной компоненты (тэг),

union {

переменные компоненты

}< имя>;

........................................................

}< имя структуры>;

Тэгом называют переменную, значение которой определяет, какой элемент объединения занимает память в данный момент.

Пример.

Паспортные данные:

- фамилия имя отчество,

- серия, номер,

- дата рождения,

- место рождения,

- национальность,

- прописка,

- семейное положение: холост|женат|разведен,

- переменная часть,

- военнообязанный: да|нет.

enum sem_pol{holost, genat, razveden};

struct pasport{

char fio[30];

char nomer[12];

data birthdate;


Поделиться:



Последнее изменение этой страницы: 2017-04-12; Просмотров: 303; Нарушение авторского права страницы


lektsia.com 2007 - 2024 год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! (0.337 с.)
Главная | Случайная страница | Обратная связь