6.x – Резюме к главе 6 и небольшой тест
Краткое резюме
В этой главе мы рассмотрели много материала. Хорошая работа!
Составная инструкция или блок – это группа из нуля или более инструкций, которая обрабатывается компилятором, как если бы это была одна инструкция. Блоки начинаются с символа {
и заканчиваются символом }
, а выполняемые инструкции помещаются между ними. Блоки можно использовать везде, где разрешено использование одной инструкции. В конце блока точка с запятой не нужна. Блоки часто используются вместе с инструкциями if
для выполнения нескольких инструкций.
Пользовательские пространства имен – это пространства имен, которые вы определяете для своих собственных объявлений. Пространства имен, предоставляемые C++ (например, глобальное пространство имен) или библиотеками (например, пространство имен std
), не считаются пользовательскими пространствами имен.
Вы можете получить доступ к объявлению в пространстве имен с помощью оператора разрешения области видимости (::
). Оператор разрешения области видимости сообщает компилятору, что идентификатор, указанный правым операндом, следует искать в области видимости левого операнда. Если левый операнд не указан, предполагается, что используется глобальное пространство имен.
Локальные переменные – это переменные, определенные внутри функции (включая параметры функции). Локальные переменные имеют область видимости блока, что означает, что они находятся в области видимости от точки определения до конца блока, в котором они определены. Локальные переменные имеют автоматическую продолжительность хранения, то есть они создаются в точке определения и уничтожаются в конце блока, в котором они определены.
Имя, объявленное во вложенном блоке, может затенять или скрывать переменную с таким же именем во внешнем блоке. Этого следует избегать.
Глобальные переменные – это переменные, определенные вне функций. Глобальные переменные имеют область видимости файла, что означает, что они видны с момента объявления до конца файла, в котором они объявлены. Глобальные переменные имеют статическую продолжительность, что означает, что они создаются при запуске программы и уничтожаются при ее завершении. По возможности избегайте динамической инициализации статических переменных.
Связывание идентификатора определяет, относятся ли другие объявления с таким же именем к этому же объекту или нет. Локальные переменные не имеют связывания. Идентификаторы с внутренним связыванием можно увидеть и использовать в одном файле, но они недоступны из других файлов. Идентификаторы с внешним связыванием можно увидеть и использовать как из файла, в котором они определены, так и из других файлов исходного кода (с помощью предварительного объявления).
По возможности избегайте использования неконстантных глобальных переменных. Глобальные переменные const
обычно считаются приемлемыми. Если ваш компилятор поддерживает C++17, используйте встраиваемые (inline
) переменные для глобальных констант.
Локальным переменным можно задать статическую продолжительность хранения с помощью ключевого слова static
.
Инструкции using
(включая объявления using
и директивы using
) могут использоваться, чтобы избежать необходимости уточнять идентификаторы явным пространством имен. Обычно их следует избегать.
Наконец, C++ поддерживает безымянные пространства имен, которые неявно обрабатывают всё содержимое пространства имен, как если бы оно имело внутреннее связывание. C++ также поддерживает встраиваемые (inline) пространства имен, которые предоставляют некоторые примитивные возможности управления версиями пространств имен.
Небольшой тест
Вопрос 1
Исправьте следующую программу:
#include <iostream>
int main()
{
std::cout << "Enter a positive number: ";
int num{};
std::cin >> num;
if (num < 0)
std::cout << "Negative number entered. Making positive.\n";
num = -num;
std::cout << "You entered: " << num;
return 0;
}
Ответ
#include <iostream> int main() { std::cout << "Enter a positive number: "; int num{}; std::cin >> num; if (num < 0) { // здесь необходим блок, чтобы, если num < 0, выполнялись обе инструкции std::cout << "Negative number entered. Making positive.\n"; num = -num; } std::cout << "You entered: " << num; return 0; }
Вопрос 2
Напишите файл с именем constants.h, который поможет запуститься следующей программе. Если ваш компилятор поддерживает C++17, используйте переменные inline constexpr
. В противном случае используйте обычные переменные constexpr
. Для max_class_size
вы можете выбрать любое значение.
main.cpp:
#include "constants.h"
#include <iostream>
int main()
{
std::cout << "How many students are in your class? ";
int students{};
std::cin >> students;
if (students > constants::max_class_size)
std::cout << "There are too many students in this class";
else
std::cout << "This class isn't too large";
return 0;
}
Ответ
constants.h:
#ifndef CONSTANTS_H #define CONSTANTS_H namespace constants { // удалите ключевое слово inline, если C++17 не поддерживается inline constexpr int max_class_size{ 35 }; } #endif
main.cpp:
#include "constants.h" #include <iostream> int main() { std::cout << "How many students are in your class? "; int students{}; std::cin >> students; if (students > constants::max_class_size) std::cout << "There are too many students in this class"; else std::cout << "This class isn't too large"; return 0; }
Вопрос 3
Завершите следующую программу, написав функцию passOrFail()
, которая должна возвращать true
для первых 3 вызовов и false
для последующих.
Подсказка
Используйте статическую локальную переменную, чтобы запомнить, сколько раз passOrFail()
вызывалась ранее.
#include <iostream>
int main()
{
std::cout << "User #1: " << (passOrFail() ? "Pass" : "Fail") << '\n';
std::cout << "User #2: " << (passOrFail() ? "Pass" : "Fail") << '\n';
std::cout << "User #3: " << (passOrFail() ? "Pass" : "Fail") << '\n';
std::cout << "User #4: " << (passOrFail() ? "Pass" : "Fail") << '\n';
std::cout << "User #5: " << (passOrFail() ? "Pass" : "Fail") << '\n';
return 0;
}
Программа должна выдать следующий результат:
User #1: Pass
User #2: Pass
User #3: Pass
User #4: Fail
User #5: Fail
Ответ
#include <iostream> bool passOrFail() { static int passes{ 3 }; return (--passes >= 0); } int main() { std::cout << "User #1: " << (passOrFail() ? "Pass\n" : "Fail\n"); std::cout << "User #2: " << (passOrFail() ? "Pass\n" : "Fail\n"); std::cout << "User #3: " << (passOrFail() ? "Pass\n" : "Fail\n"); std::cout << "User #4: " << (passOrFail() ? "Pass\n" : "Fail\n"); std::cout << "User #5: " << (passOrFail() ? "Pass\n" : "Fail\n"); return 0; }