Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Sb98050

.pdf
Скачиваний:
3
Добавлен:
13.02.2021
Размер:
403.74 Кб
Скачать

МИНОБРНАУКИ РОССИИ

––––––––––––––––––––––––––––––––––––––––––––––––––––

Санкт-Петербургский государственный электротехнический университет «ЛЭТИ» им. В. И. Ульянова (Ленина)

–––––––––––––––––––––––––––––––––––––––––––

М. С. ПЕЛЕВИН

ВВЕДЕНИЕ В ПРОГРАММИРОВАНИЕ НА ЯЗЫКЕ C++ С ПРАКТИЧЕСКИМИ ЗАДАНИЯМИ

Учебно-методическое пособие

Санкт-Петербург Издательство СПбГЭТУ «ЛЭТИ»

2019

1

УДК 004.43(07) ББК З 973-0.18 П24

Пелевин М. С.

П24 Введение в программирование на языке C++ с практическими заданиями: учеб.-метод. пособие. СПб.: Изд-во СПбГЭТУ «ЛЭТИ», 2019. 30 с.

ISBN 978-5-7629-2454-2

Содержит основные теоретические сведения о языке C++, а также практические задания.

Предназначено для подготовки бакалавров по направлению 09.03.02 «Информационные системы и технологии».

УДК 004.43(07) ББК З 973-0.18

Рецензенты: факультет информационных технологий и программирования Университета ИТМО (канд., техн. наук, доцент Тесля Н. Н.); канд. техн. наук, инженер технического контроля АО СПИИРАН-НТБВТ Гальяно Сизаско Ф. Р.

Утверждено редакционно-издательским советом университета

в качестве учебно-методического пособия

ISBN 978-5-7629-2454-2

© СПбГЭТУ «ЛЭТИ», 2019

2

1.ТИПЫ ДАННЫХ

1.1.Общие понятия

Типом данных в программировании называют совокупность двух множеств: множество значений и множество операций, которые можно выполнять над значениями. Например, к типу данных целых неотрицательных чисел, состоящему из конечного множества натуральных чисел, можно применить операции сложения (+), умножения (*), целочисленного деления (/), нахождения остатка (%) и вычитания (−).

Язык программирования, как правило, имеет набор примитивных типов данных – типы, предоставляемые языком программирования как базовая встроенная единица. В C++ такие типы создатель языка1 называет фундаментальными типами. Фундаментальными типами2 в C++ являются:

логический (bool);

символьный (напр., char);

целый (напр., int);

с плавающей точкой (напр., float);

перечисления (определяется программистом);

void.

Помимо перечисленных типов используются следующие типы:

указательные (напр., int*);

массивы (напр., char[]);

ссылочные (напр., double&);

другие структуры.

Перейдем к понятию литерала (напр., 1, 2.4F, 25e-4, ‘a’ и др.): литерал – запись в исходном коде программы, представляющая собой фиксированное значение. Другими словами, литерал – это отображение объекта (значения) какого-либо типа в исходном коде программы. В C++ есть возможность записи целочисленных значений, значений с плавающей точкой, символьных, булевых, строковых.

Литерал целого типа можно записать в разных системах счисления:

– в 10-й системе счисления: 1205;

1Разработчиком стандарта языка C++ является Бьерн Страуструп.

2Типы, соответствующие базовым принципам организации компьютерной памяти и самым общим способам хранения информации.

3

в 8-й системе счисления в формате 0 + число: 0142;

в 16-й системе счисления в формате 0x + число: 0x2F.

24, 030, 0x18 – это запись одного и того же числа в разных системах счисления. Для записи чисел с плавающей точкой используют запись через точку: 0.1, .5, 4., либо в экспоненциальной записи – 25e-100 (пробелов в такой записи быть не должно).

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

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

const int example = 3;

//здесь const – спецификатор

//int – базовый тип

//example – имя переменной

//= 3 – инициализатор.

Имя переменной является последовательностью символов из букв латинского алфавита (строчных и прописных), цифр и/или знака подчеркивания, однако первый символ цифрой быть не может3. Имя переменной следует выбирать таким, чтобы всегда было легко догадаться о том, что она хранит, например, «monthPayment». Имя переменной не может совпадать с зарезервированными в языке словами. Примеры таких слов: if, while, function, goto, switch и др.

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

* – указатель (перед именем);

& – ссылка (перед именем);

[] – массив (после имени);

3 Регулярное выражение для имени выглядит следующим образом: [_A-Za-z][_A-Za-z0-9]*.

4

– () – функция (после имени).

Инициализатор позволяет определить для переменной ее значение сразу после объявления. Инициализатор начинается с литерала равенства (=), и далее происходит процесс задания значения переменной. Вообще, знак равенства в C++ обозначает операцию присваивания, с ее помощью можно задавать и изменять значение переменной.

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

Объявить константу без инициализации не получится, поскольку значение не может быть изменено в дальнейшем:

const int EMPTY_CONST; // ошибка, не инициализована константная переменная const int EXAMPLE = 2; // константа со значением 2

EXAMPLE = 3; // ошибка, попытка присвоить значение константной переменной

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

1.2.Основные типы данных

1.2.1.Целочисленный тип (char, short (int), int, long (int), long long)

Из названия легко понять, что множество значений состоит из целых чисел. Также множество значений каждого из перечисленных типов может быть знаковым (signed) или беззнаковым (unsigned). Количество элементов, содержащееся в множестве, зависит от размера памяти, которая используется для хранения значения этого типа. Например, для переменной типа char отводится 1 байт памяти, поэтому будет всего 28 * N = 28 * 1 = 256 элементов, где N – размер памяти в байтах для хранения значения. В таком случае диапазоны доступных целых чисел следующие:

[0..255] – для беззнакового char;

[−128..127] – для знакового char.

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

unsigned long values; // задает целый (длинный) беззнаковый тип

5

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

1 = размер char ≤ размер short ≤ размер int ≤ размер long.

Обычно размеры типов следующие: char – 1, short – 2, int – 4, long –8, long long – 8 байт.

Со значениями целого типа можно совершать арифметические операции: +, -, *, /, %; операции сравнения: ==, !=, <=, <, >, >=; битовые операции: &, |, ^, <<, >>.

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

Целочисленное деление (/) находит целую часть от деления одного целого числа на другое. Например:

6 / 4 = 1;

2 / 5 = 0;

8 / 2 = 4.

Символ процента (%) обозначает операцию определения остатка от деления двух целых чисел:

6 % 4 = 2;

10 % 3 = 1.

Более сложные для понимания операции – битовые: & (И), | (ИЛИ), xor (исключающее ИЛИ), << (побитовый сдвиг влево), >> (побитовый сдвиг вправо).

Битовые операции И, ИЛИ и XOR к каждому биту информации применяют соответствующую логическую операцию:

110 = 012;

310 = 112;

110 & 310 = 012 & 112 = 012;

110 | 310 = 012 | 112 = 112;

110 ^ 310 = 012 ^ 112 = 102.

Если переменная беззнакового типа, тогда результатом будет число 156, для знакового оно равно −100. Отметим, что для знаковых целых типов единица в старшем разряде битового представления – признак отрицательности числа. При этом значение, в двоичном виде состоящее из всех единиц, соот-

6

ветствует −1; если же 1 только в старшем разряде, а в остальных разрядах – нули, тогда такое число имеет минимальное для конкретного типа значения:

для char это −128.

1.2.2. Тип с плавающей точкой

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

float value = 0.2;

value == 0.2; // ошибка, value здесь не будет равно 0.2

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

value - 0.2 < 1e-6; // ok, подбирать интервал тоже нужно осторожно

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

1.2.3. Булевый тип

Данный тип состоит всего из двух значений: true (правда) и false (ложь). Для работы с переменными данного типа используют логические операции: ! (НЕ), == (равенство), != (неравенство), && (логическое И), || (логическое ИЛИ). Результат каждой операции можно найти в соответствующей таблице истинности, например:

X

Y

XOR

0

0

0

0

1

1

1

0

1

1

1

0

1.2.4. Символьный тип

Тип char – не только целый тип (обычно такой тип называют byte), но и символьный, хранящий номер символа из таблицы символов ASCII. Например, код 0x41 соответствует символу ‘A’, а 0x71 – ‘t’.

7

Иногда возникает необходимость использования символов, которые не закреплены в таблицы ASCII, и поэтому требуют для хранения более 1-го байта. Для них существует широкий символ (wchar_t).

1.2.5. Массивы

Массивы позволяют хранить последовательный набор однотипных элементов. Массив хранится в памяти непрерывным блоком, поэтому нельзя объявить массив, не указав его размер4. Чтобы объявить массив, после имени переменной пишут квадратные скобки ([]) с указанием его размера. Например:

int myArray[5]; // Массив из 5-ти элементов целого типа

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

int odds[] = {1, 3, 7, 9, 11}; // Массив инициализируется 5-ю значениями

Для доступа к определенному значению в массиве (элемента массива) используют операцию доступа по индексу ([]) с указанием номера элемента (номера начинаются с 0). Например:

odds[0]; // доступ к первому элементу массива. Вернет значение 1 odds[2]; // доступ к третьему элементу. Вернет значение 7

odds[4] = 13; // пятому элементу массива присваиваем новое значение odds[5]; // ошибка доступа

1.2.6. Строки

Для записи строки программисты используют идею о том, что строка – последовательный ряд (массив) символов. Для идентификации конца строки применяют специальный символ конца строки: ‘\0’. Такие специальные символы, состоящие из обратного слэша и идентифицирующего символа, называют управляющими или escape-символами. Существуют, например, символы ‘\n’ – начало новой строки, ‘\t’ – табуляция. Для записи в строке обратного слэша применяют экранирование: перед самим знаком ставят еще один слэш: ‘\\’. Экранирование также применяют для записи кавычек.

Создадим переменную строки:

char textExample[5] = {‘T’, ‘e’, ‘s’, ‘t’, ‘\0’}; // записана строка «Test»

4 Размером массива называют количество элементов в нем.

8

Существует упрощенная запись инициализации строки:

char textExample[5] = “Test”; // Последний символ не пишется, но размер все еще 5

Не вдаваясь в подробности, приведем еще один полезный тип данных – string. Строки такого типа можно, например, складывать:

string hello = "Привет, "; string name = "Макс!";

string hello_name = hello + name; // Получится строка «Привет, Макс!»

1.2.7. Ссылка

Ссылка – объект, указывающий на какие-либо данные, но не хранящий их. Например:

int a = 2; // переменная a указывает на значение 2

int &b = a; // переменная b указывает туда же, куда и «a»

b = 4; // меняя значение b, программист меняет значение a. Теперь a = 4

int &c = 4; // ошибка, так делать нельзя, т. к. ссылке нельзя присвоить значение

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

1.2.8. Указатель

Чтобы разобраться с этим типом данных, необходимо запомнить, что множество значений этого типа – адреса ячеек памяти, откуда начинаются данные. Также указатель поддерживает операции сложения (+), вычитания (−) и разыменовывания (*).

Адрес 0x0 означает, что указатель пуст, т. е. не указывает ни на какие данные. Этот адрес имеет свой литерал – NULL:

int *nullPtr = NULL; // пустой указатель

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

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

9

int valueInMemory = 2; // задаем переменную целого типа

int *somePtr = &valueIntMemory; // копируем адрес переменной, здесь

& – возвращает адрес переменной

somePtr; // адрес ячейки памяти, например, 0x2F

*somePtr; // значение хранится в 4-х ячейках: 0x2F, 0x30, 0x31 и 0x32

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

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

1.2.9. Перечисления

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

enum color {RED, BLUE, GREEN};

По умолчанию RED = 0, BLUE = 1, GREEN = 2. Поэтому значения можно сравнивать между собой, т. е. RED < BLUE < GREEN. Программист при объявлении перечисления может самостоятельно задать значения каждой из констант:

enum access {READ = 1, WRITE = 2, EXEC = 4};

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

810 = 000010002.

Результат сложения этих чисел между собой всегда однозначно указывает на то, какие числа складывались:

3710 = 001001012 = 000000012 + 000001002 + 001000002 = 110 + 410 + 3210.

1.2.10. Void

Синтаксически тип void относится к фундаментальным типам, но использовать его можно лишь как часть более сложных типов, так как объектов типа void не существует. Как правило, этот тип используется для информи-

10

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]