Краткие теоретические сведения 


Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

Краткие теоретические сведения



 

Типы данных, определяемые пользователем

 

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

 

Переименование типов.

 

Для того чтобы сделать программу более ясной, можно задать встроенному типу новое имя с помощью ключевого слова typedef:

typedef тип новое_имя_типа;

или для типов – массивов

typedef тип новое_имя_типа [ размерность ][…];

В данном случае квадратные скобки являются элементом синтаксиса. Размерность может отсутствовать. Примеры:

typedef unsigned int UINT;

typedef char Msg[100];

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

UINT i, j; // объявление двух переменных типа unsigned int

Msg st; // объявление переменной st, как строки из 100 символов

Msg str[10]; // объявление массива str из 10 строк по 100 символов

Таким образом, typedef используется:

1. для задания типам с длинными описаниями более коротких псевдонимов;

2. для облегчения переносимости программ: если машинно-зависимые типы объявить с помощью операторов typedef, при переносе программы потребуется внести изменения только в эти операторы.

 

Тип перечисление

 

Тип перечисление позволяет задать связанное множество символических целых констант. Эти константы называются элементами перечисления. Отличие от эквивалентных им описаний со спецификацией const состоит в том, что нет адреса памяти, связанного с каждым элементом перечисления. Поэтому применение к элементу перечисления операции взятия адреса является ошибочным.

Перечисление описывается со служебным словом enum и разделенным запятыми списком элементов перечисления:

enum {false, true};

По умолчанию первому элементу перечисления присваивается значение 0. Каждому последующему элементу перечисления присваивается значение на 1 большее, чем значение предыдущего элемента. Так в предыдущем примере false = 0, true = 1.

Значение можно явно присвоить элементу перечисления:

enum {two = 2, three, four, ten = 10, eleven, fifty = ten + 40};

Константе two присваивается значение 2, константам three и four присваиваются значения 3 и 4, константе eleven – 11.

Имена перечисляемых констант должны быть уникальными, а значения могут совпадать. Преимущество применения перечисления перед описанием именованных констант и директивой #define состоит в том, что связанные константы нагляднее; кроме того, компилятор при инициализации констант может выполнять проверку типов.

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

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

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

enum имя-этикетка {имя_константы [= значение],...};

Например:

enum Status {Success = 1,Wait, Proceed, Error = -1 };

В операторе enum после закрывающей фигурной скобки можно сразу объявить несколько переменных данного типа:

enum Status {Success = 1,Wait, Proceed, Error = -1 } ProclStatus, Proc2Status;

Нужно иметь в виду, что имя-этикетка не является настоящим именем типа. Именем типа будет в вышеприведенном примере enum Status. Соответственно переменные должны объявляться как

enum Status ProclStatus, Proc2Status;

Однако всегда можно воспользоваться ключевым словом typedef и ввести для перечисления подлинное новое имя. Обычно это делается сразу:

typedef enum имя-этикетка {список_констант} имя_типа;

Предыдущее объявление можно переписать так:

typedef enum _Status {

Success = 1,

Wait, Proceed,

Error = -1 } Status;

Тогда Status будет полноценным именем перечислимого типа. (Обратите внимание, что для этикетки мы указали имя _Status. Это обычная практика.)

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

Status Psk = Success;

Status Psk = 1; // ошибка

 

Тип структура

 

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

struct имя {список элементов} [переменные];

Список элементов состоит из объявлений, аналогичных объявлениям переменных. Объявления элементов оканчиваются точкой с запятой. Вот пример структуры, предназначенной для хранения основных сведений о человеке:

struct Person {

char lastName[32]; // Фамилия.

char firstName[32]; // Имя.

Sex sex; // Пол: перечислимый тип (male, female).

short age; // Возраст.

long phoneNum; // Телефон как длинное целое.

} aPerson; // Объявляет переменную типа struct Person.

Переменная aPerson имеет свойства структуры Person.

Элементы структуры еще называются полями структуры. Они могут иметь любой тип, кроме типа этой же структуры, но могут быть указателями на него.

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

struct {

char fio[30];

int date, code;

double salary; }stuff[100], *ps;

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

struct Worker  // определение нового типа Worker

{ char fio[30];

int date, code;

double salary;

};

// определение массива типа Worker и указателя на тип Worker:

Worker stuff[100], *ps;

Определить новый тип структуры можно иначе:

typedef struct

{ char fio[30];

int date, code;

double salary;

} Worker;

Имя Worker можно использовать в дальнейшем наряду со стандартными типами.

Имя структуры можно использовать сразу после его объявления (определение можно дать позднее) в тех случаях, когда компилятору не требуется знать размер структуры, например:

struct List; // объявление структуры List

struct Link //определение структуры Link

{

List *p;   // указатель на структуру List

Link *prev, *succ;  // указатели на структуру Link

}:

struct List { /* определение структуры List */};

Это позволяет создавать связные списки структур.

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

struct{

char fio[30];

int date, code;

double salary; }worker = {"Страусенке", 31, 215, 3400.55};

При инициализации массивов структур следует заключать в фигурные скобки каждый элемент массива (учитывая, что многомерный массив – это массив массивов):

struct complex

{

 float real, im;

} compl [2][3] = {

{{1, 1}, {1, 1}, {1, 1}}    // строка 1. то есть массив compl[0]

{{2, 2}, {2, 2}, {2, 2}}   // строка 2, то есть массив compl[l]

};

Доступ к полям структурной переменной выполняется с помощью операций выбора "." (точка) при обращении к полю через имя переменной или ссылку и "->" при обращении через указатель, например:

 

Worker worker1, worker2, stuff[100];

………..

worker1.fio = "Страусенке";//доступ к полю fio через имя переменной

stuff[8].code = 215;          // доступ к полю code через имя переменной

Worker &stf= stuff[50];

stf.date = 31;                    // доступ к полю date через ссылку

Worker *ps=&worker2;

ps->salary = 0.12;               // доступ к полю salary через указатель

 

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

struct A {int a; double x:};

struct В {A a; double x;} х[2];

х[0].а.а = 1;

х[1].х = 0.1;

Как видно из примера, поля разных структур могут иметь одинаковые имена, поскольку у них разная область видимости. Более того, можно объявлять в одной области видимости структуру и другой объект (например, переменную или массив) с одинаковыми именами, если при определении структурной переменной использовать слово struct, но лучше этого не делать – запутать компилятор труднее, чем себя.

 

Операции со структурами.

 

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

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

 

Битовые поля в структуре.

 

Битовые поля – это особый вид полей структуры. Они используются для плотной упаковки данных, например, флажков типа «да/нет». Минимальная адресуемая ячейка памяти – 1 байт, а для хранения флажка достаточно одного бита. При описании битового поля после имени через двоеточие указывается длина поля в битах (целая положительная константа):

struct Options{

bool centerX:1;

bool centerY:1;

unsigned int shadow:2;

unsigned int palette:4; };

Битовые поля могут быть любого целого типа. Имя поля может отсутствовать, такие поля служат для выравнивания на аппаратную границу. Доступ к полю осуществляется обычным способом – по имени. Адрес поля получить нельзя, однако в остальном битовые поля можно использовать точно так же, как обычные поля структуры. Следует учитывать, что операции с отдельными битами реализуются гораздо менее эффективно, чем с байтами и словами, так как компилятор должен генерировать специальные коды, и экономия памяти под переменные оборачивается увеличением объема кода программы. Размещение битовых полей в памяти зависит от компилятора и аппаратуры.

Рассмотрим небольшой пример. Допустим, необходимо создать структуру, содержащую информацию о дате и времени некоторых событий. Этого можно добиться следующим путем:

struct DATETIME

{

unsigned short Year; // год

unsigned short Month; // месяц

unsigned short Date; // дата

unsigned short Hour; // часы

unsigned short Minute; // минуты

unsigned short Second; // секунды

};

Таким образом, объект типа DATETIME в памяти будет занимать 6(элементов) х 2(байта) = 12 байт. Нетрудно заметить, что в описании такой структуры присутствует значительная избыточность, так как год может принимать значения от 0 до 99 (задействуется всего 7 бит), месяц - от 1 до 12 (4 бита), дата - от 1 до 31 (5 бит), часы, минуты и секунды - от 0 до 59 (по 6 бит на каждый элемент). Применяя битовые структуры, приведенная выше структура примет вид:

struct DATETIME2

{

unsigned short Year:7; // год

unsigned short Month:4; // месяц

unsigned short Date:5; // дата

unsigned short Hour:6; // часы

unsigned short Minute:6; // минуты

unsigned short Second:6; // секунды

};

 

Экземпляр модифицированного типа DATETIME2 будет занимать не 12, а 5 байт (так как 34 бита могут быть размещены только в пяти байтах).

 

 

Задание к лабораторной работе №11

 

Задание 1

1. Описать структуру с именем STUDENT, содержащую следующие поля:

• NAME – фамилия и инициалы;

• GROUP – номер группы;

• SES – успеваемость (массив из пяти элементов).

2. Написать программу, выполняющую следующие действия:

• ввод с клавиатуры данных в массив STUD1, состоящий из десяти структур типа STUDENT; записи должны быть упорядочены по возрастанию содержимого поля GROUP и выведены на экран;

• вывод на дисплей фамилий и номеров групп для всех студентов, включенных в массив, если средний балл студента больше 4,0;

• если таких студентов нет, вывести соответствующее сообщение.

 

Задание 2

1. Описать структуру с именем AEROFLOT, содержащую следующие поля:

• NAZN – название пункта назначения рейса;

• NUMR – номер рейса;

• TIP – тип самолета.

2. Написать программу, выполняющую следующие действия:

• ввод с клавиатуры данных в массив AIRPORT, состоящий из семи элементов типа AEROFLOT; записи должны быть упорядочены по возрастанию номера рейса и выведены на экран;

• вывод на экран номеров рейсов и типов самолетов, вылетающих в пункт назначения, название которого совпало с названием, введенным с клавиатуры;

• если таких рейсов нет, выдать на дисплей соответствующее сообщение.

 

Задание 3

1. Описать структуру с именем WORKER, содержащую следующие поля:

• NAME – фамилия и инициалы работника;

• POS – название занимаемой должности;

• YEAR – год поступления на работу.

2. Написать программу, выполняющую следующие действия:

• ввод с клавиатуры данных в массив TABL, состоящий из десяти структур типа WORKER; записи должны быть размещены по алфавиту и выведены на экран;

• вывод на дисплей фамилий работников, чей стаж работы в организации превышает значение, введенное с клавиатуры;

• если таких работников нет, вывести на дисплей соответствующее сообщение.

 

 

Задание 4

1. Описать структуру с именем TRAIN, содержащую следующие поля:

• NAZN – название пункта назначения;

• NUMR – номер поезда;

• TIME – время отправления.

2. Написать программу, выполняющую следующие действия:

• ввод с клавиатуры данных в массив RASP, состоящий из восьми элементов типа TRAIN; записи должны быть размещены в алфавитном порядке по названиям пунктов назначения и выведены на экран;

• вывод на экран информации о поездах, отправляющихся после введенного с клавиатуры времени;

• если таких поездов нет, выдать на дисплей соответствующее сообщение.

 

Задание 5

1. Описать структуру с именем MARSH, содержащую следующие поля:

• BEGST – название начального пункта маршрута;

• TERM – название конечного пункта маршрута;

• NUMER – номер маршрута.

2. Написать программу, выполняющую следующие действия:

• ввод с клавиатуры данных в массив TRAFIC, состоящий из восьми элементов типа MARSH; записи должны быть упорядочены по номерам маршрутов и выведены на экран;

• вывод на экран информации о маршруте, номер которого введен с клавиатуры;

• если таких маршрутов нет, выдать на дисплей соответствующее сообщение.

 

Задание 6

1. Описать структуру с именем MARSH, содержащую следующие поля:

• BEGST – название начального пункта маршрута;

• TERM – название конечного пункта маршрута;

• NUMER – номер маршрута.

2. Написать программу, выполняющую следующие действия:

• ввод с клавиатуры данных в массив TRAFIC, состоящий из восьми элементов типа MARSH; записи должны быть упорядочены по номерам маршрутов и выведены на экран;

• вывод на экран информации о маршрутах, которые начинаются или кончаются в пункте, название которого введено с клавиатуры;

• если таких маршрутов нет, выдать на дисплей соответствующее сообщение.

 

Задание 7

1. Описать структуру с именем NOTE, содержащую следующие поля:

• NAME – фамилия, имя;

• TELE – номер телефона;

• BDAY – день рождения (массив из трех двузначных чисел).

2. Написать программу, выполняющую следующие действия:

• ввод с клавиатуры данных в массив BLOCKNOTE, состоящий из восьми элементов типа NOTE; записи должны быть размещены по алфавиту и выведены на экран;

• вывод на экран информации о людях, чьи дни рождения приходятся на месяц, значение которого введено с клавиатуры;

• если таких нет, выдать на дисплей соответствующее сообщение.

 

Задание 8

1. Описать структуру с именем ZNAK, содержащую следующие поля:

• NAME – фамилия, имя;

• ZODIAC – знак Зодиака;

• BDAY – день рождения (массив из трех двузначных чисел).

2. Написать программу, выполняющую следующие действия:

• ввод с клавиатуры данных в массив BOOK, состоящий из восьми элементов типа ZNAK; записи должны быть упорядочены по датам дней рождения и выведены на экран;

• вывод на экран информации о людях, родившихся под знаком, наименование которого введено с клавиатуры;

• если таких нет, выдать на дисплей соответствующее сообщение.

 

Задание 9

1. Описать структуру с именем PRICE, содержащую следующие поля:

• TOVAR – название товара;

• MAG – название магазина, в котором продается товар;

• STOIM – стоимость товара в руб.

2. Написать программу, выполняющую следующие действия:

• ввод с клавиатуры данных в массив SPISOK, состоящий из восьми элементов типа PRICE; записи должны быть размещены в алфавитном порядке по названиям товаров и выведены на экран;

• вывод на экран информации о товаре, название которого введено с клавиатуры;

• если таких товаров нет, выдать на дисплей соответствующее сообщение.

 

Задание 10

1. Описать структуру с именем ORDER, содержащую следующие поля:

• PLAT – расчетный счет плательщика;

• POL – расчетный счет получателя;

• SUMMA – перечисляемая сумма в руб.

2. Написать программу, выполняющую следующие действия:

• ввод с клавиатуры данных в массив SPISOK, состоящий из восьми элементов типа ORDER; записи должны быть размещены в порядке увеличения расчетного счета плательщика и выведены на экран;

• вывод на экран информации о сумме, снятой с расчетного счета плательщика, введенного с клавиатуры;

• если такого расчетного счета нет, выдать на дисплей соответствующее сообщение.

 

Задание 11

1. Описать структуру с именем DATA, содержащую следующие поля:

• Number – число;

• Month – месяц;

• Year – год.

2. Написать программу, вычисляющую интервал (в днях), прошедших между двумя датами.

 

Задание 12

1. Описать структуру с именем DATA, содержащую следующие поля:

• Number – число;

• Month – месяц;

• Year – год.

2. Написать программу, определяющую по порядковому номеру дня в году число и месяц года.

 

Задание 13

1. Описать структуру с именем DATA, содержащую следующие поля:

• Number – число;

•   Month – месяц;

• Year – год.

2. Написать программу, определяющую по введенной дате дату на N дней вперед.

 

Задание 14

1. Описать структуру с именем STUDENT, содержащую следующие поля:

• NAME – фамилия и инициалы;

• GROUP – номер группы;

• SES – успеваемость (массив из пяти элементов).

2. Написать программу, выполняющую следующие действия:

• ввод с клавиатуры данных в массив STUD1, состоящий из десяти структур типа STUDENT; записи должны быть упорядочены по возрастанию среднего балла и выведены на экран;

• вывод на дисплей фамилий и номеров групп для всех студентов, имеющих оценки 4 и 5;

• если таких студентов нет, вывести соответствующее сообщение.

 

Задание 15

1. Описать структуру с именем AEROFLOT, содержащую следующие поля:

• NAZN – название пункта назначения рейса;

• NUMR – номер рейса;

• TIP – тип самолета.

2. Написать программу, выполняющую следующие действия:

• ввод с клавиатуры данных в массив AIPORT, состоящий из семи элементов типа AEROFLOT; записи должны быть размещены в алфавитном порядке по названиям пунктов назначения и выведены на экран.

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

• если таких рейсов нет, выдать на дисплей соответствующее сообщение.

 

 


 

Содержание отчета

 

Отчет выполняется в редакторе Word 2000 и должен содержать:

 

1. Листинг программ на языке Си, решающих задачи в соответствии с вариантом (номером компьютера) задания;

2. Блок-схему алгоритма программ;

3. Пояснения по методу решения задач;

4. Результаты тестирования программ.

 

При оформлении отчета следует пользоваться копированием листинга и результата тестирования в Word. Последний копируется с помощью комбинации клавиш ALT Prt Sc при условии активности консольного окна, что означает копирование графики окна в буфер обмена Windows. Затем окно вставляется в документ Word как любой другой объект.

 


 

ЛАБОРАТОРНАЯ РАБОТА №12

 

Потоки ввода-вывода. файлы

 

Потоки ввода-вывода.

 

Ввод/вывод на самом низком уровне интерпретируется как передача последовательности байтов между объектами. Эта последовательность байтов называется потоком. На этом уровне понятие типа данных отсутствует. В языке С++ управление потоками осуществляется с помощью функций библиотеки ввода/вывода, унаследованной от С и объявленной в заголовочном файле stdio.h или cstdio, или с помощью операторов потока ввода/вывода. К преимуществам первого способа относится возможность более гибкого управления форматированием и его полная совместимость с С. Используя операторы потока ввода/вывода, можно не задумываться о форматах вывода информации, если это не имеет принципиального значения. Кроме того, этот метод позволяет переопределить форму вывода для любого класса. Однако, одновременное использование библиотеки stdio.h и операторов потока ввода/вывода не желательно. Если без этого обойтись нельзя, то необходимо вызвать функцию sync_with_stdio().

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

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

- входные, из которых читается информация;

- выходные, в которые вводятся данные,

- двунаправленные, допускающие как чтение, так и запись.

Над потоком можно выполнять следующие операции:

- считывание блока данных из потока в оперативную память;

- запись блока данных из оперативной памяти в поток;

- обновление блока данных в потоке;

- считывание записи из потока;

- занесение записи в поток.

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

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

Файл может быть текстовым или бинарным (двоичным). Различие между ними заключается в том, что в текстовом файле последовательности символов разбиты на строки. Признаком конца строки является пара символов CR(¢\r¢ - возврат каретки («каретка» - элемент печатной машинки прошлого, название взято из машинописи и означает возврат к началу строки) и LF(¢\n¢ - перевод строки, перход на следующую строку) или - ¢\r¢+¢\n¢. При вводе информации из текстового файла эта пара символов заменяется символом CR, при выводе, наоборот, - символ CR заменяется парой символов CR и LF. Бинарный файл рассматривается как последовательность байт. При вводе и выводе информации в бинарный файл никакого преобразования символов не производится. Кроме того, в текстовом и бинарном файлах различный способ интерпретации информации. В текстовом файле числа представляются символами цифр, а в бинарном используется внутренне представление числа, которое зависит от типа компьютера. Обычно бинарные файлы используются в том случае, если они являются источником информации, которая не представляется непосредственно человеку.

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

 



Поделиться:


Последнее изменение этой страницы: 2021-11-27; просмотров: 80; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 3.17.64.47 (0.146 с.)