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

книги / Технологии разработки объектно-ориентированных программ на язык C++. Основы структурного программирования на алгоритмическом языке C++

.pdf
Скачиваний:
4
Добавлен:
12.11.2023
Размер:
3.17 Mб
Скачать

Команда system (“pause”) необходима, чтобы консоль не закрылась сразу после выполнения программы. В противном случае вы не увидите результата выполнения – консоль сразу же закроется.

Общий вид программы

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

#include необходимые библиотеки (это так называемые директивы препроцессора)

using namespace std;

некоторая функция a()

{

...

// Какие-то действия

}

 

int main() {

// Главная функция программы

...

// Какие-то действия

system (“pause”);

// Задержка для консоли

return 0;

// Программа завершилась успешно

}

 

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

Строка «using namespace std» указывает на то, что мы используем по умолчанию пространство имен с названием std. Все используемые вами переменные создаются именно в этом пространстве, и через него программа следит, чтобы имена переменных не повторялись.

Далее находятся функции. Самая главная из них – это функция int main() {}, в которой и идет основное выполнение программы. Остальные функции могут быть вызваны из главной. Функции – настолько обширная тема, что заслуживает дальнейшего подробного изучения, а пока важно понять, что всегда есть только одна главная и любое количество второстепенных.

41

8.2. Пространство имен

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

STD – это стандартное пространство имен, которое используется всеми, если нет необходимости создавать свое.

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

namespace My {

// Создаем пространство имен My

int a = 0, b = 2;

// Создаем в нем переменные

}

 

using namespace My; // Указываем, какое пространство

 

использовать

int main() {

 

a = a+b;

/* Используем переменные из нашего

 

пространства имен */

}

 

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

8.3. Основные арифметические операции

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

* (умножение);

/ (деление);

42

+ (сложение);

– (вычитание);

% (остаток от целочисленного деления). Основные унарные операции следующие:

++ (инкрементирование, т.е. увеличение на 1);

– – (декрементирование, т.е. уменьшение на 1);

– (изменение знака).

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

Рассмотрим на примере:

int one = 5; int two = 6; int three = 0;

three = one*++two;

// three = 35, поскольку в операции умножения two = 7 уже

int one = 5; int two = 6; int three = 0;

three = one * two++;

//three = 30, поскольку в операции умножения two = 6 еще

//Но после данного выражения two = 7

Бинарные арифметические операции могут быть объединены с операцией присваивания:

объект *= выражение; // объект = объект * выражение;

объект /= выражение; // объект = объект / выражение;

объект += выражение; // объект = объект + выражение;

объект –= выражение; // объект = объект – выражение;

объект %= выражение; // объект = объект % выражение.

43

8.4. Отладка программы

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

Препроцессорное преобразование текста – текстовый редактор

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

Все системные обозначения перекодируются в стандартные

коды.

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

Выполняются директивы препроцессора, и производятся макроподстановки – замена значений параметризированным текстом. Препроцессор «сканирует» исходный текст программы в поиске строк, начинающихся с символа «#». Такие строки воспринимаются препроцессором как директивы, которые определяют действия по преобразованию текста.

Замена идентификаторов заранее подготовленными последовательностями символов.

Включение в программу текстов из указанных файлов.

Esc-последовательности в символьных константах и символьных строках, например ‘\n’, заменяются на соответствующие числовые коды.

Каждая препроцессорная лексема преобразуется в лексему языка С++.

Компиляция

Компиляция относится к обработке файлов исходного кода (.c, .cc или .cpp) и созданию объектных файлов проекта. На этом этапе еще не создается исполняемый файл. Компилятор преобразует

44

полученную из предыдущего этапа заготовку в машинный язык. Например, если создать три отдельных файла, у вас будет три объектных файла, созданных в качестве выходных данных на этапе компиляции. Расширение файлов будет зависеть от компилятора, например *.obj или *.o. Каждый из этих файлов содержит машинные инструкции, которые эквивалентны исходному коду. Но на данном этапе невозможно запустить эти файлы! Их необходимо превратить в исполняемые файлы операционной системы, и только после этого их можно использовать. За это отвечает третий этап отладки.

Компоновка

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

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

Директивы препроцессора

Заголовочные файлы включаются в текст программы с помощью директивы препроцессора #include. Все директивы препроцессора начинаются со знака «#», который должен быть самым первым символом строки.

Директива #include включает в программу содержимое указанного файла. Имя файла может быть указано двумя способами:

45

#include <some_file.h> #include "my_file.h"

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

#ifndef AK_H #define AK_H

// Содержимое файла ak.h #endif

Условная директива #ifndef проверяет, не было ли значение AK_H определено ранее. AK_H – это константа препроцессора, такие константы принято писать заглавными буквами. Препроцессор обрабатывает следующие строки вплоть до директивы #endif. Если же этот файл уже включен, то препроцессор пропускает строки от

#ifndef до # endif.

Директива #define AK_H определяет константу препроцессора AK_H. Благодаря помещению этой директивы после директивы #ifndef гарантируется, что файл ak.h будет включен в исходный текст только один раз, сколько бы раз ни включался в текст сам этот файл.

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

#if – проверка условия;

#ifdef – проверка определенности идентификатора. Эта директива противоположна описанной выше #ifndef, т.е. выполняется, если файл уже включен;

#else – начало альтернативной ветви для #if;

#endif – окончание условной директивы #if, #ifdef и #ifndef.

46

8.5. Пример построения программы на С++

Дана задача: разработать и написать программу, которая считает факториал введенного пользователем числа. Использовать среду программирования Microsoft Visual Studio 2017.

Все начинается с открытия проекта (рис. 8.1). На начальной странице необходимо выбрать пункт «Создать проект». Из предложенных вариантов рекомендуется выбрать «Пустой проект». В графе «Имя» ввести имя своего проекта. Рекомендуется выбирать имя так, чтобы понимать, для чего разработан этот проект.

Рис. 8.1. Создание проекта

После того, как был создан проект, необходимо создать файл, где будет написан код программы. Правой кнопкой мыши необходимо щелкнуть на название вашего проекта, выбрать пункт «Добавить»/«Создать элемент» (рис. 8.2).

В появившемся окне нужно выбрать «Файл С++» и дать ему имя (рис. 8.3).

И в открытом окне уже следует писать программу (рис. 8.4).

47

Рис. 8.2. Создание элемента

Рис. 8.3. Создание файла для программы

48

Рис. 8.4. Написание программы

Если после написания нажать «Локальный отладчик», то программа автоматически пройдет все три этапа отладки и запустится, если нет ошибок. Но есть также пошаговая отладка, которая позволяет пройти по программе шаг за шагом, находя и исправляя ошибки и неточности.

Пошаговая отладка

Для запуска отладки нажмите кнопку F10. После нажатия этой клавиши программа запустится в отладочном режиме, и вы увидите примерно то, что изображено на рис. 8.5.

Черное окно – консоль, где будут выводиться данные из программы. Необходимо понимать, что отладка начинается с первой строчки функции main, так как она является точкой входа. Желтый курсор сле-

49

ва обозначает строчку, которая сейчас будет выполняться. Теперь если нажимать кнопки F10 (шаг с заходом в вызываемые функции) или F11 (шаг без захода в вызываемые функции), то можно опускать курсор вниз, тем самым выполняя программу постепенно, строку за строкой.

Рис. 8.5. Отладка программы

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

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

Во вкладке «Локальные переменные» можно просматривать значения переменных метода, который выполняется в текущий момент времени.

50

Соседние файлы в папке книги