Файл: Практикум по курсу информатика.pdf

ВУЗ: Не указан

Категория: Не указан

Дисциплина: Не указана

Добавлен: 10.01.2024

Просмотров: 72

Скачиваний: 1

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.

40
Данную функцию также можно использовать для вывода строковых кон- стант, заключенных в кавычки.
char getchar(); //возвращает значение символа, введенного с клавиатуры
– функция ввода символов
char putchar(char); //возвращает значение выводимого символа, выводит
на экран символ, переданный в качестве аргумента – функция вывода симво-
лов.
В Таблица 6.5 приведены некоторые из библиотечных функций, исполь- зующихся при работе с символьными строками (библиотека string.h) [4]:
Таблица 6.5
Функция
Описание
char *strcat(char *s1,char *s2) присоединяет s2 к s1, возвращает s1
char *strncat(char *s1, char *s2, int n) присоединяет не более n символов s2 к s1, завер- шает строку символом '\0', возвращает s1
char *strсpy(char *s1, char *s2) копирует строку s2 в строку s1, включая '\0', воз- вращает s1
char *strncpy(char *s1, char *s2, int n) копирует не более n символов строки s2 в строку s1, возвращает s1;
int strcmp(char *s1, char *s2) сравнивает s1 и s2, возвращает значение 0, если строки одинаковы
int strncmp(char *s1, char *s2, int n) сравнивает не более n символов строк s1 и s2, возвращает значение 0, если начальные n симво- лов строк эквивалентны
int strlen(char *s) возвращает количество символов в строке s
char *strset(char *s, char c) заполняет строку s символами, код которых ра- вен значению c, возвращает указатель на строку
s
char *strnset(char *s, char c, int n) заменяет первые n символов строки s симво- лами, код которых равен c, возвращает указа- тель на строку s

41
6.7. Задание на лабораторную работу № 3
1. Необходимо создать консольное приложение Win32, осуществляющее перевод десятичного числа со знаком в двоичное с выводом всех 32-х разрядов в прямом порядке.
2. Перевод должен быть осуществлен методом поразрядной проверки бита и логического сдвига маски.
3. На вход поступает строка, содержащая натуральное десятичное число
«a» в диапазоне -2 147 483 648…2 147 483 647. В строке возможны ошибки, такие как лишние символы, буквы, превышение длинны строки. Их необхо- димо исправить. Всего на вход может поступить до 100 строк.
4. Выход из программы происходит после ввода пользователем 0, перед выходом запрашивается подтверждение выхода.
5. Вывод сделать в виде таблицы со столбцами: номер, число, двоичный код числа.
6.8. Пояснения к лабораторной работе № 3
1. Данные вводим с клавиатуры как строку:
char sIn[100];// размер с запасом
scanf_s(“%s”,sIn);//указатель на строку это имя строковой переменной.
Удаляем из строки ошибочные символы так: а) делаем перебор символов в строке, и если это цифра и не знак «минус», то символ записываем в исправленную строку, а иначе символ пропускается; б) в исправленной строке не забываем символ окончания – нуль; в) копируем исправленную строку в исходную; г) если в строке были ошибки возвращаем код ошибки.
2. Разберемся со структурой проекта. Требуется написать код самого при- ложения и создать отдельную библиотеку. Код приложения – это текстовый файл с расширением .cpp. Библиотека состоит из двух файлов – файла заго- ловка с расширением .h и файла с текстом функций библиотеки (определени- ями функций) с расширением .cpp. Эту структуру легко понять из примера повторного использования кода предыдущей лабораторной работы. В том коде есть только один файл .cpp с нужной нам функцией Fun. Но подключить этот файл к нашему проекту помешает функция main, в новом коде функция с этим названием уже есть, а две функции с одинаковыми именами main
компи- лятор не пропустит. Значит, нужные в других проектах функции следует вы- носить в отдельные файлы, а их объявления - в отдельные заголовки.


42
Создайте файл приложения, например, Application.cpp. Создайте файлы библиотеки, например, MyLip.cpp и MyLib.h. с помощью меню по правой кнопке на вашем проекте в окне решения: Add\New item.
В начале файла Application.cpp перечисляются подключаемые библио- теки, например, стандартная библиотека stdafx.h. Подключим и нашу соб- ственную библиотеку:
#include “MyLib.h”
Такая же строка будет и в начале файла MyLip.cpp.
Целесообразно в файл MyLip.cpp перенести все сложные самостоятельно созданные функции, например: функцию ввода числа и его проверки на ошибки, функцию вывода в виде строк таблицы и т. д. Определения функций выглядят так:
//определение функции
int FunctionName(int a, int b)//тип функции(int, bool, void и т.д.), ее имя и
аргументы на входе
{
int c = a + b;//содержание функции – что она делает
return c;//возвращаемое значение
}
В файле заголовка MyLib.h помещаются объявления функций, которые выглядят так:
int FunctionName(int a, int b); //объявление функции
Все функции, определенные в MyLip.cpp, должны быть объявлены в
MyLib.h, иначе компилятор их не увидит. Также ошибки возникают, если ар- гументы функции в определении и в объявлении не совпадают.
3. По условию задачи на вход поступает число в формате строки, при этом в строке могут быть ошибки. Строка – набор символов, каждый из которых можно проверить. Сделать это можно с помощью функции isdigit(). Функция возвращает TRUE, если символ на ее входе является цифрой:
//пример использования функции isdigit()
char str[6] = "12abc";//пример строки
if (isdigit(str[1])) // проверка, является ли символ с индексом [1] цифрой
printf("This is digit");//результат проверки
else
printf("Not digit");
Обратите внимание, что символ минус «-» не является цифрой, но должен быть сохранен, так как пользователь может ввести отрицательное число.

43
При правильном вводе строка может содержать до 12 символов (10 цифр, знак «-» и 0 – символ конца строки). Из-за ошибок длина вводимой строки может оказаться больше, так что максимальную длину строки можно сделать
20–30 символов.
4. В процессе проверки строки лишние символы исключаются, в резуль- тате останется новая строка, содержащая число и, возможно, знак «-». Ее можно преобразовать в целое число int , воспользовавшись функцией atoi():
//пример использования функции atoi()
char str[3] = "42"; // в памяти записаны ASCII-коды цифр 4 и 2
int num = atoi(str); //num = 42, в памяти записано само число 42.
Функция atoi() корректно преобразует и положительные, и отрицатель- ные числа. В примере в ячейках памяти, выделенных для хранения числа 42, будет записано: 00000000000000000000000000101010. Это и есть двоичный код числа, который требуется вывести в таблицу. Для того чтобы «достать» этот двоичный код и вывести его в виде строки, воспользуемся методом по- разрядной проверки бита и логического сдвига маски.
5. Результаты требуется вывести в таблицу. Известно, что в таблице будет не более 100 записей. При этом в одной строке таблицы будет располагаться двоичный код числа (32 символа), само число (до 11 символов) и номер строки
(до 3 символов), всего 46 символов. Между столбцами для удобства чтения следует сделать пробелы. Таким образом, для одной строки будет достаточно взять 50 символов: 46 для информации, 3 для пробелов и 1 для перевода на новую строку. Такая таблица представляет собой двумерный массив:
char Tab[100][50];
Заполнение строк таблицы происходит по ходу обработки вводимых пользователем чисел. Ввод происходит циклически, условий окончания два – введено 100 строк, либо введено число нуль. Для такого ввода удобно исполь- зовать цикл с постусловием do while:
int strNumber = 0;//переменная для индекса строки (номер строки – на 1
больше!)
do
{
//Происходит ввод числа и запись его в таблицу
...
//StrNumber++ – каждый цикл увеличивается индекс строки
} while (Value!=0 && StrNumber < 99); //пока число не ноль и введено
меньше 100 строк, продолжить.


44
Не забудьте перед выводом таблицы вывести названия столбцов «Но- мер», «Значение», «Двоичный код», :
printf("Num Value Bin\n");
Далее нужно вывести таблицу по строкам. Напомним, что вся таблица Tab в этом случае считается массивом строк. Чтобы таблица была аккуратной, каждую строку следует заполнять текстом, выделяя для каждой колонки до- статочно символов.
Колонка с порядковым номером, например, содержит текст длиной от од- ного до 3-х символов, колонка числа от одного до 11 символов, включая знак, двоичный код фиксированный размер 32 символа. Колонки заканчиваются разделителем – символом пробела или вертикальной чертой.
Вывод текста заданного размера в колонку можно реализовать, добавляя в строку с текстом пробелы по количеству недостающих символов. Оформите в вашей библиотеке функцию вывода десятичного числа в поле заданного раз- мера.

45
1   2   3   4   5   6

7. СТРУКТУРЫ
Иногда требуется описать несколько свойств одного и того же объекта.
Например, в списке студентов вуза может быть такая информация: имя (набор символов), номер группы и номер в списке (целые числа). Эти переменные имеют различные типы. Можно объявить их индивидуально: int group, int
number, string name – и так для каждого студента. Но с увеличением числа сту- дентов в списке количество отдельных переменных будет расти, всем им по- требуется присвоить различные имена, так что работать с таким кодом будет затруднительно.
Казалось бы, можно создать массив из трех элементов, в первый его эле- мент записать имя, во второй – номер группы и так далее. Но наши перемен- ные имеют различные типы, а массивы могут содержать элементы только од- ного типа. Так что такой способ не подойдет.
Другой вариант – использовать различные массивы: в одном хранить все имена, в другом – все номера. Но эти массивы надо синхронизировать, ведь изменения в одном массиве должны учитываться во всех остальных, что со- здает дополнительные сложности. Поэтому для решения данной задачи в Cи существуют структуры данных.
Структурой в языке Cи называется совокупность переменных различ- ного типа, формирующих составной тип, который программист может объяв- лять самостоятельно.
Структуру можно объявить тремя способами, которые приведены в Таб- лица 7. 1:
Таблица 7. 1
Способ 1 (С++)
Способ 2 (Си)
Способ 3 (комбинирован- ный)
struct MyStruct_s
{
int group, number;
char name[200];
};
typedef struct
{
int group, number;
char name[200];
} MyStruct_t;
typedef struct MyStruct_s
{
int group, number;
char name[200];
} MyStruct_t;
Рассмотрим первый способ объявления структуры. В нем используется ключевое слово struct, и выбирается имя структуры, например, MyStruct_s.
Внутри записываются поля (элементы) структуры и их типы. Мы создали

46 новый составной тип данных – шаблон, который программа будет использо- вать, когда мы объявим переменную-структуру: MyStruct_s Student.
Второй способ использует ключевое слово typedef. Здесь тип данных не
имеет названия, но имеет псевдоним MyStruct_t. Этот псевдоним можно ис- пользовать так же, как и обычный тип данных. С помощью typedef
можно за- давать псевдонимы и для стандартных типов, важно не запутаться в переопре- делениях.
Третий способ совмещает два предыдущих – создается тип данных
MyStruct_s, и ему присваивается псевдоним MyStruct_t.
При создании переменной Student типа MyStruct_s в памяти выделяется место для нее. В данном случае будет выделено по 4 байта для элементов group и number, 200 байт для символов поля name – всего 208 байт, что проиллю- стрировано на Рис. 16.
Рис. 16. Расположение структуры в памяти
Для доступа к элементам структуры указывается имя переменной и назва- ние элемента: Student.group = 4321. Это значит, что в переменную типа int, занимающую первые 4 байта переменной Student, запишется число 4321. Ад- рес переменной &Student.group – это адрес первого байта памяти, в которой хранится переменная Student.
Пример заполнения строки имени: strcpy_s(Student.name, 200, "Peter")
При этом от начала переменной Student отсчитывается 8 байт, в память скопи- руется строка «Peter», а затем добавится 0 – символ конца строки.
К элементам структуры можно получить доступ с помощью указателя:
MyStruct_s Student;
MyStruct_s *pStudent = &Student;
strcpy_s(pStudent->name, 200, "Peter");
Структуры могут содержать десятки элементов. Чтобы не присваивать каждому из них значение индивидуально, можно инициализировать всю структуру сразу: MyStruct_s Example = {4, 2, "QWERTY" };

47
Если при инициализации в скобках записаны не все переменные, то остав- шимся числовым переменным будут присвоены нулевые значения.
7.1. Состав структуры
Структура может содержать следующие элементы:
− простые переменные (int, double, char и т. д.);
− индексированные переменные (в качестве элементов структуры могут использоваться массивы);
− другие структуры (не допускается рекурсия типов – внутри структуры не может содержаться такая же структура);
− указатели.
7.2. Особенности работы со структурами
Так же, как и обычные переменные, структуры одного типа можно копи- ровать:
MyStruct_t A = { 1,2, "ABC" };
MyStruct_t B = { 0,0, "0" };
B = A; //копирование содержимого одной структуры (A) в другую (B)
Можно создавать массивы из структур. При этом используются квадрат- ные скобки, как и для обычного массива, а номер элемента массива пишется перед точкой:
MyStruct_t Array[5]; //массив, состоящий из 5 структур
Array[2].number = 15; //во второй элемент третьей структуры в мас-
сиве записывается 15
По аналогии с обычными индексированными переменными, Array – это указатель на первый элемент массива, так что Array->group это то же самое, что и Array[0].group.
7.3. Передача структур в функции
Аргументы типа структур передаются в функции разными способами:
1. По значению – function(MyStruct_s F). В этом случае в памяти создается копия структуры. Все изменения, происходящие с копией, не затрагивают ис- ходную структуру. Такой способ может быть неэффективен, если структура очень большая.
2. По указателю – function(MyStruct_s *F). В этом случае передается только адрес структуры, копия в памяти не создается. Чтобы действиявнутри

48 функции не изменяли содержимого структуры, может использоваться моди- фикатор const: function (const MyStruct _s *F).
3. По ссылке – function(MyStruct_s &F). Здесь тоже можно использовать модификатор const, если надо подчеркнуть, что память переменной не будет изменена при работе функции.
Аналогично, в функцию можно передавать только части структур:
1. По значению – function (F.number). Будет создана копия переменной.
2. По указателю – function (&F.number). Передается только адрес.
3. По ссылке – function (F.number). Тоже передается только адрес.
7.4. Битовые поля и объединения
Битовые поля позволяют определить точное количество бит, которые ис- пользуются в памяти для каждого из элементов структуры. При этом через двоеточие указывается количество бит:
struct date
{
unsigned short day : 5; //максимальное число дней в месяце: 31, доста-
точно 5 разрядов
unsigned short month : 4; //максимальное число месяцев: 12, доста-
точно 4 разрядов
};
Полученный тип данных занимает 2 байта в памяти, размер его равен раз- меру unsigned short.
При этом модификатор unsigned важен, иначе один бит будет зарезервирован под знак числа.
Использование битовых полей удобно для экономии памяти.
Существуют особые структуры – объединения. Для их создания исполь- зуется слово union, например: union MyUnion {int n; char ch;};. Такая конструк- ция позволяет интерпретировать одну и ту же память или как целое, или как символ, как показано в примере ниже:
MyUnion Un;
Un.n = 75; //записываем в память целое число 75
int a = Un.n; //a = 75, память интерпретируется как целое число 75
char b = Un.ch; //b = 'K', число 75 интерпретируется как ASCII-код
буквы 'K'
Un.ch = 'G'; //записываем в память букву 'G'

49
int c = Un.n; //c = 71, ASCII-код буквы 'G' интерпретируется как целое
число 71
char d = Un.ch; //d ='G', память интерпретируется как ASCII-код 'G'
Здесь используется один и тот же байт памяти, поэтому изменение эле- мента структуры ch одновременно изменяет и элемент n.
7.5. Задание на лабораторную работу № 4
1. С использованием двух структур создать консольное приложение для записи телефонной книжки.
2. Ввод записей осуществляется, пока не будет введен телефонный номер
0;
3. Выводить записи телефонной книжки в таблицу:
− порядковый номер;
− ник;
− телефон.
4. Таблицу выводить построчно;
5. Использовать библиотеку и общее с лабораторной №3 решение.
7.6. Пояснения к лабораторной работе № 4
1. Номер телефона состоит из нескольких цифр и символа «+». Для его хранения создадим структуру:
struct PhoneNo_s // это определение нашего собственного типа
{
long long Number : 40; // почему 40 бит достаточно для телефона?
unsigned int Plus : 1; // поле для плюса
};
Чтобы сэкономить место в памяти, выделяем на номер 40 бит и один бит выделяем в качестве признака «+». Такая структура займет 8 байт, но исполь- зоваться будет только 41 бит из 64 доступных.
2. Запись в телефонной книжке тоже является структурой – она содержит номер и ник:
struct MyPhRec_s //определяет структуру тип с именем MyPhRec_s
{
PhoneNo_s PhoneNo; //номер
char Nic[MY_MAX_STR_LEN]; //ник
};

50
Поля данной структуры: ранее созданная структура номера телефона
PhoneNo_s и индексированная переменная char[] для имени абонента. Размер этой переменной можно изменять, меняя определение MY_MAX_STR_LEN.
Для этого в файле заголовка пишется следующий макрос:
#define MY_MAX_STR_LEN 40; // размер строки – 40 символов
Если потребуется изменить количество символов, достаточно поменять значение в строке с #define. Везде, где записано MY_MAX_STR_LEN, будет ис- пользовано новое значение.
Вопрос для студентов: почему для этой же цели нельзя использовать обычную переменную?
Итак, в структуре есть номер телефона, занимающий 8 байт, и имя разме- ром до 40 символов по одному байту. Всего эта структура займет 48 байт.
3. Создадим переменную, имеющую описанный тип:
MyPhRec_s rec;
Чтобы сохранить в нее номер, указываем названия нужных полей струк- туры через точку:
rec.PhoneNo.Number = 79219222222;
Поле Number находится в начале структуры PhoneNo. Структура PhoneNo находится в начале структуры rec. Число 79219222222 будет записано в пере- менную типа _int64, расположенную в начале памяти, занятой переменной rec.
К этой переменной также можно обратиться, используя адрес
&rec.PhoneNo.Number.
Заполним строку имени:
strcpy_s( rec.Nic, 40, "Peter");
Поле Nic располагается после поля Number. От начала переменной rec от- считывается 8 байт, занятых полем Number, а дальше в память копируется строка "Peter", в конце строки добавляется символ 0.
4. Если используется указатель на структуру MyPhRec_s *prec, доступ к ее элементам можно получить так:
prec->PhoneNo.Number = 79219222222;
strcpy_s(prec->Nic, 40, "Peter");
Чтобы инициализировать сразу все элементы структуры, используются фигурные скобки:
MyPhRec_s F = {{7921, 1}, "ABC"};
Здесь внешние скобки принадлежат структуре MyPhRec_s, а внутренние
– структуре PhoneNo_s.

51
8. СТРУКТУРЫ С++ И КЛАССЫ
Структура, как и всякая другая переменная в коде имеет область видимо- сти от того места, где она определяется до конца блока. Тут мы встречаем опе- рацию создания структуры, в С++ это функция, называемая конструктор. Она может быть явно не задана, тогда это просто выделение памяти под структуру.
В конце блока память, занимаемая структурой, освобождается, и в С++ эта операция тоже может быть дополнена некоторыми действиями в функции, называемой деструктором.
8.1. Конструкторы в структурах
В описании структуры как типа данных можно определять функции, ини- циализирующие данные – конструкторы. Использование конструкторов упрощает задание начальных значений элементов структур, которые иначе пришлось бы перечислять по одному, присваивая им начальные значения в тексте после объявления переменной данного типа. Если не присвоить началь- ные значения, в переменной может оказаться «мусор», оставшийся от преды- дущего владельца этой памяти. Пример:
struct PhoneNo_s // определение нашего собственного типа
{
long long Number : 40; //40 бит достаточно для номера телефона
unsigned int Plus : 1; // поле для плюса, 1 бит
PhoneNo_s(long long Num, unsigned int Pls) : Number(Num), Plus(Pls) {}
//инициализирующий конструктор, оба поля структуры PhoneNo_s будут за-
писаны значениями из списка параметров конструктора
PhoneNo_s() : Number(0), Plus(0) {} // конструктор без параметров,
записывает в поля 0
};
Имя функции-конструктора должно совпадать с именем типа, которому она принадлежит. В нашем примере PhoneNo_s – единственно возможное имя конструктора. Мы написали два варианта конструкторов: конструктор с пара- метрами long long Num и unsigned int Pls, которые будут записаны в элементы структуры, и конструктор без параметров, в котором элементы инициализиру- ются нулями. Конструкторы без параметров еще называются конструкторами
по умолчанию.

52
8.2. Полиморфизм конструкторов
Свойство языка различать две и более функций с одинаковыми именами в С++ называется полиморфизмом. Хотя нельзя изменить имя функции (как в случае с конструктором), можно изменить количество или тип параметров функции. В зависимости от типов параметров при вызове в коде будет вызван нужный вариант конструктора:
PhoneNo_s P(); // будет вызван конструктор без параметров (по умол-
чанию) и элементы Number и Plus будут инициализированы нулями
PhoneNo_s P( 799211234567, 1 ); // будет вызван конструктор c пара-
метрами и будут инициализированы элементы Number числом 799211234567
и Plus числом 1.
Аналогично и для структуры телефонной книжки, которая содержит эле- мент PhoneNo с типом структуры телефонного номера PhoneNo_s:
#define MY_MAX_STR_LEN 50
struct MyPhRec_s //определяет структуру тип с именем MyPhRec_s
{
PhoneNo_s PhoneNo;//номер
char Nic[MY_MAX_STR_LEN];//короткое имя контакта
MyPhRec_s(long long Num, unsigned int Pls, const char* Nm) : Pho-
neNo(Num, Pls) { strcpy_s(Nic, MY_MAX_STR_LEN, Nm); } {}
// это инициализирующий конструктор, одно поле структуры
MyPhRec_s и два поля PhoneNo_s будут записаны значениями из списка пара-
метров конструктора
MyPhRec_s(): PhoneNo(), Nic("") {} // это конструктор без парамет-
ров, записывает в поля 0
};
Здесь конструкторы (с параметрами и без) структуры MyPhRec_s сперва вызывают соответствующие конструкторы вложенной структуры PhoneNo_s.
В синтаксисе конструктора после знака двоеточия «:» можно перечислять че- рез запятую конструкторы элементов этой структуры. В С++ конструкторы есть и у простых типов. Например, имя простой переменной со скобками Num-
ber(Num) – это вызов конструктора типа long long со значением Num. Это зна- чение Num и будет записано в элемент телефонного номера нашей структуры.
В блоке кода конструктора также можно присваивать значения элементам.
Вызывать другие конструкторы этой же структуры из блока кода
конструктора небезопасно.

53
8.3. Наследование в типах С++
Обратим внимание, что действия в конструкторах структуры MyPhRec_s вызывают конструкторы ее вложенной структуры. Здесь просматривается иерархия наших данных, которой в Си не было. Можно считать структуру
MyPhRec_s некоторой надстройкой над структурой PhoneNo_s. В MyPhRec_s появляется еще один атрибут Nic – имя контакта в телефонной книжке.
Итак, мы пришли к еще одному важному свойству данных в С++, которое называется наследованием. Предназначение базового типа PhoneNo_s – работа с данными телефонного номера. Его наследник MyPhRec_s должен опериро- вать еще и именем контакта. Иерархия типов удобна, она экономит код, авто- матически включая в наследников функционал базовых типов.
8.4. Инкапсуляция переменных в классах
Дальнейшее развитие языка С при переходе к С++ основано на принципе объединения переменных и действий над ними в классы. Действия реализу- ются с помощью функций и операторов, определяемых внутри этих классов.
То есть, если структуры могли иметь только функции-конструкторы, то для классов допустимы любые другие функции. Эти функции должны быть объ- явлены в определении класса.
Класс объявляется словом class, за ним следует имя этого класса. Дей- ствуют те же ограничения на имена, что и у простых переменных. Затем сле- дует блок текста C++, содержащего объявление переменных и функций класса. Классы не поддерживаются компиляторами простого Си. Если в текстах файлов заголовков вам нужно использовать классы, а сами заголовки подключаются в тексты простого Си, возникает конфликт. Он разрешается за- ключением С++ определений классов в блок с условием для препроцессора:
#ifdef __cplusplus … #endif. Полезные сведения о классах можно подчерпнуть из [5]
8.5. Ограничения доступа к элементам и функциям классов
В С++ введено понятие прав доступа к содержимому класса. Права бы- вают:
public – доступ без ограничений;
protected – доступ из внутренних функций этого класса и его наследни- ков;
private – доступ только из внутренних функций этого класса, наследни- кам не разрешен.

54
Public, protected, private – это спецификаторы типа доступа. Группы пе- ременных и функций в объявлении класса располагаются ниже соответствую- щего спецификатора.
Основными функциями в классах являются конструктор и деструктор.
Конструктор вызывается при объявлении переменной нашего класса. Деструк- тор вызывается, когда переменная класса выходит из области видимости в тек- сте.
Во время сборки компилятор проверяет, есть ли в коде переменные с ти- пом нашего класса. Если ни одной такой переменной нет, код класса не будет включен в код проекта. Никакие функции этого класса работать не будут.
8.6. Переменные внутри классов
Все переменные, которые вы делаете элементами класса, имеют область видимости, включающую все функции данного класса, независимо от уровня доступа. При этом возникает аналогия с глобальными переменными в простом
Си, только глобальность ограничивается функциями класса.
В функциях класса переменные класса не нужно передавать как пара- метры – они уже доступны для чтения и записи. Если запись не предполага- ется, переменная объявляется с префиксом const. Если переменные объявлены в классе как public, то они доступны из внешнего по отношению к классу кода.
Пример:
class CPhoneNo // определение нашего класса телефонного номера
{
public:
long long Number : 40; // номер
unsigned int Plus : 1; // поле для плюса
CPhoneNo(long long Num, unsigned int Pls) : Number(Num), Plus(Pls) {}
// инициализирующий конструктор, оба элемента класса СPhoneNo будут
записаны значениями из списка параметров конструктора
CPhoneNo():Number(0), Plus(0) {} // конструктор без параметров, за-
писывает в элементы класса 0
CPhoneNo() {} // деструктор
bool Input(); // функция ввода номера с клавиатуры
bool Input(const char* strAsk); // функция ввода номера с клавиатуры с
запросом оператору
};

55
Инициализация тех переменных класса, которые имеют фиксированные значения, должна быть явно выполнена в конструкторе, иначе значения пара- метров будут неопределенными.
Два экземпляра одноименной функции допустимы, так как различаются списком параметров:
bool Input(); //функция без параметров
bool Input(const char* strAsk); //функция с параметром – строкой (для
приглашения)
Это правило распространяется на все функции, как описанные в классе, так и внешние обычные функции.
Рассмотрим, почему это удобно. Пусть есть одно и то же действие, кото- рое по-разному выполняется для разных типов данных: ToBin(int N) и
ToBin(long long N). Типы аргументов у этих функций разные, так что получа- ются два экземпляра функции перевода в двоичный код – для 32-битных и для
64-битных целых чисел.
Рассмотрим пример кода:
CPhoneNo PhNo(); // создается переменная объекта с типом CPhoneNo
нашего класса.
//в скобках нет аргументов: вызывается конструктор без параметров,
в переменные класса записываются 0
//переменная объявлена и класс «инстанцирован», т.е. его переменные
доступны в коде как данные, и функции класса доступны в вызывающем коде
PhNo.Number = 792312345678; // присваиваем значение, так как теле-
фонный номер доступен для записи (public)
if( PhNo.Number ) {/*код, выполняемый по условию*/}// оператор условия
использует разрешенный доступ на чтение к переменной Number
Классы идеально подходят для повторного использования кода. Класс мо- жет определяться как наследник другого класса, называемого в этом случае
базовым или родительским. Это значит, что наследующий класс может вклю- чить все переменные (как это было в структурах) и функции базового класса автоматически, без дублирования кода. В нашем случае класс записи телефон- ной книжки может быть наследником класса телефонного номера:
class CMyPhRec : public CPhoneNo // запись телефонной книжки насле-
дует свойства номера телефона
{
public:

56
CMyPhRec(__int64 Num, unsigned int Pls, const char* Nm) : CPho-
neNo(Num, Pls) { strcpy_s(Nic, MY_MAX_STR_LEN, Nm); }
// конструктор явно вызывает конструктор базового класса
CPhoneNo
CMyPhRec() {}// деструктор
char Nic[MY_MAX_STR_LEN];// переменная определенная в классе
};
Классы как параметры передаются в функции теми же способами, что и обычные переменные, в частности структуры (см. п. 7.3).Передача элементов класса в функцию возможна только для public элементов.
Классы удобно помещать в отдельные файлы. В файле заголовка (.h) находятся объявления классов. Объявление класса содержит его компоненты, то есть переменные и объявления функций, но не содержит код (определение) этих функций. Код функций (методов класса) помещается в файл .cpp.
Все переменные класса и его базовых классов являются локальными пе- ременными внутри этого класса. Например, Number и Plus в классе CPhoneNo будут доступны (видны) внутри функции Input(). Следовательно, при исполь- зовании классов сокращается список параметров функции.
Вызов функции класса осуществляется так же, как и обращение к пере- менной класса. Например:
F.Input();//вызывает функцию ввода телефонного номера для переменной
F класса CPhoneNo.
В файле .срр определение функции дается с указанием имени класса и разделителем пространства имен «::»:
CPhoneNo::Input()
{// здесь записывается код функции Input()}
Наконец, классы позволяют определять функции – действия над перемен- ными, объявленными принадлежащими к этому классу. Такие функции назы- ваются операторами. Примером может быть оператор присваивания «=». Он позволяет нам сделать копирование A = B; для переменных класса. При этом выполняется «осмысленное» копирование переменных из экземпляра B в эк- земпляр A класса. Например, возможен такой оператор копирования:
CPhoneNo operator =(CPhoneNo& in) { this->Number = in.Number;
this->Plus = in.Plus; return *this; }// this – это указатель на сам экземпляр
класса, который стоит в левой части оператора.

57
Для класса существует пространство имен (namespace). Переменные и функции класса находятся внутри этого пространства имен. Это значит, что к имени каждой переменной или функции добавляется имя класса, например:
CPhoneNo::Input();
В программе могут быть и другие функции Input(), однако имя класса де- лает нашу функцию Input() уникальной и позволяет компилятору отличать ее от других. Компилятор будет искать определение такой функции в первую очередь внутри данного класса.
Внутри класса пространство имен присваивается по умолчанию. Напри- мер, если вы при описании функции класса вызываете другую функцию или переменную этого же класса, префикс CPhoneNo:: не нужен. Его можно доба- вить, и это не будет ошибкой.
8.7. Классы как переменные и массивы
Переменные класса можно присваивать:
CMyPhRec A(), B(79219222222, 1, "ABC" );
A = B; // содержимое нормально скопируется из B в A, включая внутрен-
нюю структуру, если в классе есть оператор присваивания.
Индексированные переменные – это массивы, элементами которых явля- ются переменные с типом этого класса. Синтаксис будет таким же, как и у структур: квадратные скобки с номером, затем точка. Например:
СMyPhRec Ar[2];//массив классов длиной 2 элемента;
Ar[1].Number = 10;//во второй элемент массива и в первый элемент
класса в первый элемент PhoneNo записать 10
По аналогии с обычными индексированными переменными Ar – указа- тель на первый элемент массива, а Ar>Nic – это то же, что и Ar[0].Nic.
8.8. Задание на лабораторную работу № 5
1. С использованием двух классов создать консольное приложение для за- писи телефонной книжки.
2. Ввод записей осуществлять, пока не будет введен телефонный номер
«0».
3. Выводить записи телефонной книжки в таблицу в алфавитном порядке:
− порядковый номер;
− ник;
− телефон.
4. Таблицу выводить построчно.

58 5. Использовать библиотеку и общее с лабораторными № 3–4 решение.
8.9. Пояснения к лабораторной работе № 5
В наше решение, где уже есть часть нужных функций, добавляем проект лабораторной работы. Для этого в представлении Solution (Ctrl+Alt+L) щел- каем правой кнопкой мыши на имени нашего решения и в вызванном меню выбираем пункты Add и Project. Далее создаем консольное приложение как в разделе 1 «Создание проекта в среде разработки Microsoft Visual Studio».
Создание классов в Microsoft Visual Studio облег- чается встроенным помощником. Для этого пе- рейдите в представление классов, обычно оно располагается в закладке под структурой реше- ния, Ctrl+Shift+C (Рис. 17).
В этом представлении можно видеть уже имеющиеся классы нашего приложения и доба- вить новый класс, для чего меню по правой кнопке мышки на нашем проекте имеет пункт
Add и подменю Class. Появляется окно создания класса (Рис. 18).
Рис. 18. Окно создания класса
В этом окне вводим имя класса и определяем файлы заголовка (.h) и тек- ста (.cpp). Объявление класса помещается в файл .h, а конструктор – в файл
.cpp. При наличии базового класса автоматически будет добавлен заголовок, где этот класс объявлен и заполнены соответствующие зависимости в объяв- лении классов. Аналогично добавляем функции и переменные в класс через пункт меню Add, щелкнув правой кнопкой мыши на строчке нужного класса в
Рис. 17. Представление классов

59 окне представления классов. Заготовки для функций с типами и списками до- бавленных вами параметров будут созданы автоматически.
Сортировку массива можно выполнить по алгоритму из пункта 10.3 (сор- тировка методом «камешка»).

60
9. СТАНДАРТНЫЕ БИБЛИОТЕКИ С++
Стандартные библиотеки С++ предоставляют пользователям большое ко- личество полезных классов и функций, выполняющих типовые алгоритмы.
Алгоритмы хранения данных обобщаются в классах, которые относят к группе
«коллекции». Стандартные классы и функции помещаются в пространстве имен «std::», для сокращения текста вверху обычно помещают директиву using
namespace std.
9.1. Класс vector – векторы, динамические массивы
Динамический массив экономит память в процессе работы программы, а автоматический еще и освобождает память по окончании использования.
В языке С++ введено понятие шаблона – это возможность описать дей- ствия над неопределенным типом данных. При этом компилятор сам допишет нужный код с учетом конкретного типа данных, который передается в шаблон как параметр. Шаблон использует для определения типа синтаксис угловых скобок .
Шаблон классов динамических массивов выглядит так: std::vector , где Т – тип данных, которые хранит массив.. Библиотеку векторов нужно под- ключить в виде заголовка следующим образом:
#include
Вектор назван так, поскольку представляет собой одномерный массив.
Вектор из векторов масштабирует функционал в два измерения.
Конструкторы std::vector создают объект этого типа в коде и инициали- зируют переменную данными:
vector phBook; // вводится переменная без параметров,
компилятор вызывает конструктор без параметров, так что phBook – пу-
стой массив длиной 0;
vector vecInt(vecIntOther); // копирующий конструктор: вводится
новая переменная, которую компилятор заполняет копией другого вектора
(можно не целиком, а в выбранном диапазоне);
vector vecInt(100, 1); //заполняющий конструктор: вводится пере-
менная, компилятор заполняет массив единицами;
Когда переменная класса std::vector выходит из области видимости, вы- зываются деструкторы всех элементов массива, сам массив тоже удаляется.
Векторы поддерживают функции, которые синтаксически тождественны операциям:
std::vector A,B(5,1); //создаем два объекта

61
A=B; //присваиваем одному объекту значения другого
Здесь вызывается оператор «=» класса std::vector. Этот оператор на самом деле – функция класса. Обычно функции имеют буквенные имена, но эта функция имеет имя «=», то есть выглядит как знак равенства. Это очень по- хоже на присваивание в Си. В результате содержимое B будет скопировано в
A, причем с сохранением порядка следования.
Существует также оператор вида «[]», тогда B[0] будет содержимым пер- вого элемента массива, в нашем случае числом 1. То есть наши привычные действия с вектором, как с массивом, работают через эту функцию-оператор.
Важнейшая операция – добавление в вектор нового значения. Для этого используется функция push_back(value). Чтобы стереть последнее значение в векторе, используется pop_back(). При этом размер вектора size() в первом слу- чае увеличится, а во втором – уменьшится на 1. Все действия по выделению и освобождению памяти будут выполнены автоматически.
Ниже представлены еще несколько полезных функций:
vector::size(); //возвращает количество элементов вектора;
vector::empty(); // возвращает true для пустого вектора;
vector::clear(); //удаляет все из вектора.
Для векторов и других классов коллекций определен класс перебора эле- ментов вектора, который называется итератором: vector::iterator. Значе- ние итератора – адрес соответствующего элемента, то есть указатель на эле- мент с типом T*.
Для вектора определены итераторы начала vector::begin(), который ука- зывает на первый элемент вектора, и конца vector::end(), который указывает
за пределы вектора.
У итератора есть тип, полное название которого выглядит так:
std::vector::iterator i. В нашем тексте auto i – синоним из С++ 11, то есть компилятор автоматически подставит вместо auto этот длинный тип
std::vector::iterator. Так что использование синонимов в таких случаях улучшает читабельность кода.
У итератора существуют унарные операторы «*», «&», «++», а также опе- раторы сравнения «==», «!=».
Приведем простую аналогию с циклом перебора Си:
for( int i = 0; i < phBook.size(); i++ )
CMyPhRec rc = phBook[i];
То же самое можно записать с помощью итератора:
for( auto i = phBook.begin(); i!= phBook.end(); i++ )

62
CMyPhRec rc = *i;
Использовать сравнение итераторов «<» и «>» не рекомендуется, хотя данные в массиве должны строго находиться в непрерывной области памяти, чтобы арифметика указателей работала.
В классе std::vector хранятся данные, и функция data() предоставит до- ступ к данным начиная с первого элемента массива. Кроме того, очевидно, в классе хранится длина вектора, но эта переменная защищена (вот для чего ну- жен доступ protected) и доступна нам только через функцию size().
В С++ существует класс std::string для работы с текстами. У класса строк базовый класс это vector и, как следует из изложенного, С++ строки наследуют функции векторов (в том числе сложение, копирование, размер и пр.) [6].
9.2. Задание на лабораторную работу № 6
1. С использованием двух классов создать консольное приложение для за- писи телефонной книжки.
2. Ввод записей осуществлять пока не будет введен телефонный номер
«0».
3. Выводить записи телефонной книжки в таблицу в алфавитном порядке, сортировка методом «камушка» (см. раздел 10):
− порядковый номер;
− ник;
− телефон.
4. Таблицу выводить построчно.
5. Использовать библиотеку и общее с лабораторными работами № 3, 4 и
5 решение.
9.3. Пояснения к лабораторной работе № 6
Доступ к элементам класса vector phBook производится по имени переменной с индексом. Программист при написании кода должен учи- тывать, есть ли такой элемент в векторе. Если элемента с таким индексом нет, возникнет исключение.
phBook[0].Number = 79219222222;
Эта строка означает, что компилятору нужно записать число 79219222222 в переменную типа long long, которая расположена в начале памяти, занятой переменной phBook[0]. Адрес этой переменной: &(phBook[0].Number).
Пример заполнения строки имени:
phBook[0].Nik = “Peter”;

63
Доступ к элементам класса, переданного итератором:
СMyPhRec * prec = phBook.begin();
phBook.begin() ->Number = 79219222222;
phBook.push_back(СMyPhRec(7921,1,”ABC”));//сконструирует
объект
из параметров в списке конструктора СMyPhRec и запишет его в конец век-
тора phBook.
9.4. Потоковый ввод и вывод
Потоковый ввод-вывод представляет собой функции, которые выпол- няют действия преобразования из/в текст переменных различного типа. При вводе и выводе источниками могут быть консоль, файл, буфер в памяти и, ко- нечно, различные коммуникации – USB, LAN, BlueTooth, WiFi и пр., которые играют роль символьного потока.
Действия при вводе текста можно представить как чтение последователь- ности символов – слова. Слово может быть текстом или числом. В качестве разделителей выступают пробелы, перевод строки или специальные символы.
При выводе текста необходимо преобразовывать числа в строки и обес-
печивать последовательный посимвольный вывод строк в нужный по-
ток.
В языке С++ эти действия выполняют функции и классы библиотеки
и их наследники. В данном курсе рассматриваются два класса биб- лиотеки консольного ввода-вывода:
cin – чтение из клавиатуры консоли;
cout – запись в окно консоли на экране.
Поскольку они являются частными случаями выполнения преобразова- ния из/в строку, действия по преобразованию перенесены в базовые классы
istream и ostream, которые в свою очередь являются наследниками класса
io_base.
Когда вы пишете в коде «cin» или «cout», там создаются, соответственно, объект ввода из консоли или объект вывода.
Оператор чтения из буфера ввода «>>», очевидно, имеет варианты: по ти- пам данных (int, double, char) и соответствующие операторы в классах строк.
Синтаксис оператора «>>» при этом не меняется, а нужный вариант компиля- тор находит из набора полиморфных операторов библиотеки. То же справед- ливо для оператора записи «<<».
При выводе в таблицу всегда возникает проблема форматирования, для решения которой применяется библиотека .

64
В С++ программировании существует также понятие манипулятора – объекта, изменяющего действие операторов чтения «>>» и записи «<<». Так
std::setw(int width) ограничивает количество символов, которые читаются, например, в массив, а при выводе создает строку нужной ширины. Таким об- разом можно сделать колонки в таблице. Внутри этих колонок выравнивание при выводе обеспечивается с помощью манипуляторов left (по умолчанию) или right:
std::cout << setw(20) << right << “ABC”; //АВС будет в 18-20 позициях.
Существуют также и другие полезные функции стандартной библиотеки
С++, например:
std::cin.get(char &ch) //прочитает каждый символ из потока, включая
пробелы, обычный оператор «>>» пробелы и перевод строки игнорирует
std::cin.getline( char *ch, int length) //прочитает строку с ограничением
длины.
Вместе с консольным вводом-выводом можно использовать также ввод- вывод в строку/из строки (функции такого вывода принадлежат библиотеке
)или ввод-вывод с использованием файлов (библиотека ).
Работа с файлами имеет некоторые особенности. Так, например, сперва необходимо открыть файл, для чего создается объект с типом операции
ifstream (для ввода) или ofstream (для вывода). Также желательно проверять открыт ли он. Это можно сделать следующим образом:
std::ifstream FileIn;
FileIn.open(“MyFile.txt”);
if(FileIn.is_open())//проверка что файл открыт
{FileIn >> MyStr;}//запись из файла в строку
Полный путь к файлу при записи должен обязательно содержать символы
«\\» (двойной обратный слэш), которые разделяют папки:
FileIn.open(“с:\\Tmp\\MyFile.txt”);
Чтение из файла должно сопровождаться проверкой того, что файл не за- кончился:
while ( FileIn. good()){};//один вариант проверки
while ( !FileIn. eof() ){};//другой вариант
После того как чтение или запись в файл (из файла) закончены, файл необ- ходимо закрыть, при этом он будет сохранен на диск:
FileIn.close();
Манипуляторы setw, right и т. п. при чтении и записи из/в файл точно так же наследуются классами файлового ввода/вывода.

65
9.5. Задание на лабораторную работу № 7
1. С использованием двух классов создать консольное приложение для за- писи телефонной книжки.
2. Ввод записей осуществлять, пока не будет введен телефонный номер
«0».
3. Выводить записи телефонной книжки в файл в табличном виде в алфа- витном порядке, сортировка любым методом:
− порядковый номер;
− ник;
− телефон;
4. Использовать библиотеку и общее с лабораторными № 3, 4, 5 и 6 реше- ние.
5. Реализовать функцию поиска телефона по имени методом деления на 2
(см. раздел 10).

66
10. ИСПОЛЬЗУЕМЫЕ АЛГОРИТМЫ
В данном разделе приведен краткий обзор алгоритмов обработки данных, используемых в лабораторных работах.
10.1. Алгоритм простого перебора
Для вывода телефонной книжки в алфавитном порядке нужно упорядо- чить записи при выводе, так, чтобы имена абонентов следовали по возраста- нию (ведь «B» > «A»). Для этого необходимо:
1. Найти индекс наименьшего имени в исходном массиве и поменять за- пись перового элемента с найденной местами;
2. Повторять п.1, начиная со следующего элемента, ведь предыдущий уже на месте и так до конца массива.
Чтобы найти индекс минимального элемента необходимо:
1. В цикле перебрать записи в таблице и найти наименьшее имя;
2. В новой строке запомнить имя текущего элемента, и последовательно сравнивая со следующим меньшее из них, записывать в эту строку;
3. Запомнить индекс наименьшего элемента.
10.2. Алгоритм простого перебора (вариант 2)
Чтобы поменять две записи в массиве местами, будем использовать вре- менную переменную следующим образом:
1. Заводим временную переменную с типом записи Temp;
2. Копируем в Temp содержимое первого неупорядоченного элемента;
3. Копируем в первый неупорядоченный элемент, найденный нами наименьший из оставшихся элементов;
4. На место наименьшего элемента копируем Temp.
10.3. Сортировка методом «камешка»
Для вывода телефонной книжки в алфавитном порядке нужно упорядо- чить записи при выводе, так, чтобы имена абонентов следовали по возраста- нию (ведь ASCII-код буквы B больше, чем у A и так далее).
1. Начинаем с самого верха нашего вектора: пусть i = phBook.begin(), то- гда, сравниваем этот элемент со следующим:
if ((i-> Nic) > (i++)->Nic)
{/*выполняем п.2*/}
2. Если предыдущее имя больше следующего, то сразу меняем эту запись со следующей местами;

67 3. Повторяем п.1-2, начиная со следующего элемента, но не доходим на 1 позицию до конца массива;
4. После 1–3 утверждается, что самое дальнее по алфавиту имя находится в конце массива и его больше проверять не нужно.
10.4. Сортировка методом «камешка» (вариант 2)
1. Повторяем п.1–3 из предыдущего метода для верхних N-2 элементов, потом для N-3, и так далее, пока не останется один элемент.
2. Важно: если при каком-либо проходе не было ни одной перестановки, то массив уже отсортирован. Останавливаем цикл 1–3.
3. Меняем две записи в массиве местами, используя временную перемен- ную следующим образом:
3.1. заводим временную переменную с типом записи Temp
3.2. копируем в Temp содержимое первого неупорядоченного эле- мента
3.3. копируем в первый неупорядоченный элемент, найденный нами наименьший из оставшихся;
3.4. на место наименьшего копируем Temp.
10.5. Поиск методом дихотомии (деления на 2)
Для поиска номера абонента в отсортированной в алфавитном порядке телефонной книжке можно эффективно использовать свойство последователь- ности, упорядоченной по возрастанию. Для этого необходимо:
1. Завести две переменных, соответствующих верхнему и нижнему ин- дексам интервала поиска
iTop = 0;
iBottom = PhoneBook.size()-1;
2. Найти середину (разделить пополам нашу книгу)
iMid = (iTop + iBottom)/2;
3. Проверить, в какой половине находится искомое имя: if
(PhoneBook[iMid].Nik > Name), значит в верхней, иначе: а) если равно, то поиск закончен; б) если меньше, то имя в нижней половине списка.
4. После 1–3 утверждается, что половину массива, где искомого имени нет, больше проверять не нужно.

68
10.6. Поиск методом дихотомии (вариант 2)
1. Меняем границы нашего интервала поиска на основании сравнения искомого имени с серединой интервала, см. п.10.5.
2. Если поиск продолжаем в верхней части интервала, то
iBottom = iMid.
3. Если же поиск продолжаем в нижней части интервала, то меняется верхняя граница iTop = iMid.
4. Если имя найдено, то поиск заканчивается успехом.
5. Если разница между верхним и нижним индексами равна 1, то поиск заканчивается неудачей.

69
ЗАКЛЮЧЕНИЕ
Наиболее полные сведения о языке Си с множеством полезных примеров можно найти в классической книге Б. Кернигана и Д. Ритчи [7].
Фундаментальный труд по языку С++ и способам его применения при- надлежит Б. Страуструпу [8].
Изучение этих книг позволит вам расширить знания по курсу информа- тики до уровня профессионала.

70
СПИСОК ИСПОЛЬЗОВАННЫХ ИСТОЧНИКОВ
1. ГОСТ 19.701-90 (ИСО 5807-85) Единая система программной документации
(ЕСПД). Схемы алгоритмов, программ, данных и систем. // Электронный фонд правовой и нормативно-технической информации [Электронный ресурс].
URL: https://docs.cntd.ru/document/9041994 (дата обращения: 19.10.2021).
2. Массивы // Викичтение [Электронный ресурс]. URL: https://it.wikiread- ing.ru/4163 (дата обращения: 19.10.2021).
3. Дэвис Стефан Р. C++ для «чайников», 4-е издание. : Пер. с англ. : — М. : «И.
Д. Вильямс», 2003.
4. Обработка строк: стандартная библиотека string // Программирование
[Электронный ресурс]. URL: https://prog-cpp.ru/c-string/ (дата обращения
19.10.2021).
5. Введение в классы С++ // Программирование на С и С++ [Электронный ре- сурс]. URL: http://www.c-cpp.ru/books/vvedenie-v-klassy-s (дата обращения:
19.10.2021).
6. cplusplus reference string // cplusplus.com [Электронный ресурс]. URL: https://www.cplusplus.com/reference/string/string/ (дата обращения: 20.10.2021).
7. Керниган Брайан У., Ритчи Дэвис М. Язык программирования С, 2-е изд. :
Пер. с англ. — М.: ООО «И.Д. Вильямс», 2017.
8. Бьерн Страуструп Язык программирования C++. Специальное издание. Пер. с англ. — М.: Издательство Бином, 2011 г. — 1136 с: ил.

71
ПРИЛОЖЕНИЕ
МИНОБРНАУКИ РОССИИ
САНКТ-ПЕТЕРБУРГСКИЙ ГОСУДАРСТВЕННЫЙ
ЭЛЕКТРОТЕХНИЧЕСКИЙ УНИВЕРСИТЕТ
«ЛЭТИ» ИМ. В.И. УЛЬЯНОВА (ЛЕНИНА)
Кафедра РЭС
ОТЧЕТ
по лабораторной работе
№ А
по дисциплине «Информатика»
1   2   3   4   5   6


Тема:
Студент(ка) гр.
Фамилия И.О.
Преподаватель
Фамилия И.О.
Санкт-Петербург
202А

72
ОГЛАВЛЕНИЕ
ВВЕДЕНИЕ .............................................................................................................. 3 1. СТРУКТУРА ОТЧЕТА ПО ЛАБОРАТОРНОЙ РАБОТЕ .............................. 4 1.1. Титульный лист ............................................................................................. 4 1.2. Содержание .................................................................................................... 5 1.3. Спецификация задания ................................................................................. 5 1.4. Формализованное описание алгоритма решения задачи .......................... 5 1.5. Блок-схема алгоритма ................................................................................... 6 1.6. Выбор и обоснование типов переменных. ................................................. 7 1.7. Вводимые и выводимые параметры и их типы ......................................... 7 1.8. Структура проекта, перечисление нужных файлов................................... 7 1.9. Результаты лабораторной работы ............................................................... 9 2. СОЗДАНИЕ ПРОЕКТА В СРЕДЕ РАЗРАБОТКИ MICROSOFT VISUAL
STUDIO .................................................................................................................. 10 3. ЭЛЕМЕНТЫ ЯЗЫКА Си .................................................................................. 17 3.1. Типы данных................................................................................................ 17 3.2. Переменные ................................................................................................. 18 3.3. Арифметические операции ........................................................................ 18 4. ЧИСЛА И ИХ ПРЕДСТАВЛЕНИЕ В МАШИННЫХ КОДАХ ................... 19 4.1. Управляющие элементы языка Си ............................................................ 19 4.2. Блоки кода .................................................................................................... 20 4.3. Функции и блоки ......................................................................................... 21 4.4. Задание на лабораторную работу № 1 ...................................................... 22 5. ОТРИЦАТЕЛЬНЫЕ ЧИСЛА В ДВОИЧНОМ КОДЕ ................................... 23 5.1. Шестнадцатеричный код ............................................................................ 23 5.2. Функции и структурирование кода ........................................................... 26 5.3. Глобальные переменные ............................................................................ 27 5.4. Параметры, передаваемые по значению ................................................... 27 5.5. Передача параметров по указателю .......................................................... 28 5.6. Передача параметров по ссылке (С++) ..................................................... 28 5.7. Отладка функций ........................................................................................ 29

73 5.8. Задание на лабораторную работу № 2 ...................................................... 29 5.9. Пояснения к лабораторной работе № 2 .................................................... 29 6. ИНДЕКСИРОВАННЫЕ ПЕРЕМЕННЫЕ ...................................................... 31 6.1. Классификация массивов ........................................................................... 31 6.2. Кодирование символов ............................................................................... 33 6.3. Инициализация и представление массивов в коде .................................. 34 6.4. Выход за границы массива ......................................................................... 37 6.5. Динамические массивы .............................................................................. 38 6.6. Работа с массивами ..................................................................................... 39 6.7. Задание на лабораторную работу № 3 ...................................................... 41 6.8. Пояснения к лабораторной работе № 3 .................................................... 41 7. СТРУКТУРЫ ..................................................................................................... 45 7.1. Состав структуры ........................................................................................ 47 7.2. Особенности работы со структурами ....................................................... 47 7.3. Передача структур в функции ................................................................... 47 7.4. Битовые поля и объединения ..................................................................... 48 7.5. Задание на лабораторную работу № 4 ...................................................... 49 7.6. Пояснения к лабораторной работе № 4 .................................................... 49 8. СТРУКТУРЫ С++ И КЛАССЫ ....................................................................... 51 8.1. Конструкторы в структурах ....................................................................... 51 8.2. Полиморфизм конструкторов .................................................................... 52 8.3. Наследование в типах С++ ......................................................................... 53 8.4. Инкапсуляция переменных в классах ....................................................... 53 8.5. Ограничения доступа к элементам и функциям классов ........................ 53 8.6. Переменные внутри классов ...................................................................... 54 8.7. Классы как переменные и массивы ........................................................... 57 8.8. Задание на лабораторную работу № 5 ...................................................... 57 8.9. Пояснения к лабораторной работе № 5 .................................................... 58 9. СТАНДАРТНЫЕ БИБЛИОТЕКИ С++ ........................................................... 60 9.1. Класс vector – векторы, динамические массивы ...................................... 60 9.2. Задание на лабораторную работу № 6 ...................................................... 62