Процедурное программирование. Конструкция ветвления. Циклы. Массивы

Содержание

Слайд 2

КОНСТРУКЦИЯ ВЕТВЛЕНИЯ. УСЛОВНЫЙ ОПЕРАТОР IF Когда программа C++ должна принять решение

КОНСТРУКЦИЯ ВЕТВЛЕНИЯ. УСЛОВНЫЙ ОПЕРАТОР IF

Когда программа C++ должна принять решение

о том, какое из альтернативных действий следует выполнить, такой выбор обычно реализуется оператором if. Этот оператор имеет две формы: просто if и if else.
Давайте сначала исследуем простой if. Он создан по образцу обычного английского языка, как в выражении "If you have a Captain Cookie card, you get a free cookie" (игра слов на основе созвучности фамилии Кук и слова "cookie" (печенье) — прим. перев.). Оператор if разрешает программе выполнять оператор или блок операторов при условии истинности проверочного условия и пропускает этот оператор или блок, если проверочное условие оценивается как ложное. Таким образом, оператор if позволяет компилятору принимать решение относительно того, нужно ли выполнять некоторую часть кода.
Синтаксис оператора if :
if (проверочное-условие)
оператор;
Слайд 3

Оператор IF Условная конструкция в С++ всегда записывается в круглых скобках

Оператор IF

Условная конструкция в С++ всегда записывается в круглых скобках после

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

Оператор IF if (num cout } else{ // иначе cout }

Оператор IF

if (num <10) { // Если введенное число меньше 10.


cout<<"Это число меньше 10."<< endl;
}
else{ // иначе
cout<<"Это число больше либо равно 10."<< endl;
}
Здесь говорится: «Если переменная num меньше 10 — вывести соответствующее сообщение. Иначе вывести другое сообщение».
Усовершенствуем программу так, чтобы она выводила сообщение, о том, что переменная num равна десяти:
Слайд 5

Оператор IF Заметьте, что во втором условии, при проверке равенства, мы

Оператор IF

Заметьте, что во втором условии, при проверке равенства, мы используем

оператор равенства = = (двойное «равно»), а не оператор присваивания (=), потому что мы не изменяем значение переменной при проверке, а сравниваем ее текущее значение с числом 10.
Если поставить оператор присваивания в условие, то при проверке условия значение переменной изменится, после чего это условие выполнится.
Каждому оператору if соответствует только один оператор else. Совокупность этих операторов —if else означает, что если не выполнилось предыдущее условие, то проверить данное. Если ни одно из условий не верно, то выполняется тело оператора else.
Слайд 6

Оператор IF Если после оператора if, else или их связки else

Оператор IF

Если после оператора if, else или их связки else if

должна выполняться только одна команда, то фигурные скобки можно не ставить. Предыдущую программу можно записать следующим образом:
#include
Usingnamespacestd;
Intmain() {
setlocale(0, "");
doublenum;
cout<<"Введите произвольное число: "; cin>> num;
if (num <10) // Если введенное число меньше 10.
cout<<"Это число меньше 10."<< endl;
else if (num == 10)
cout<<"Это число равно 10."<< endl;
else// иначе
cout<<"Это число больше 10."<< endl;
return0;
}
Слайд 7

Оператор IF Такой метод записи выглядит более компактно. Если при выполнении

Оператор IF

Такой метод записи выглядит более компактно. Если при выполнении условия

нам требуется выполнить более одной команды, то фигурные скобки необходимы. Например:
#include
Using namespace std;
Int main() {
setlocale(0, "");
double num;
Int k;
cout<<"Введите произвольное число: "; cin>> num;
if (num <10) { // Если введенное число меньше 10.
cout<<"Это число меньше 10."<< endl;
k = 1;
}
Else if (num == 10) { cout<<"Это число равно 10."<< endl;
k = 2;
}
else{ // иначе
cout<<"Это число больше 10."<< endl;
k = 3;
}
cout<<"k = "<< k << endl;
return0;
}
Слайд 8

Оператор IF Данная программа проверяет значение переменной num. Если она меньше

Оператор IF

Данная программа проверяет значение переменной num. Если она меньше 10,

то присваивает переменной k значение единицы. Если переменная num равна десяти, то присваивает переменной k значение двойки. В противном случае — значение тройки. После выполнения ветвления, значение переменной k выводится на экран.
Слайд 9

Оператор Switch (переключатель) Предположим, что вы создаете экранное меню, которое предлагает

Оператор Switch (переключатель)

Предположим, что вы создаете экранное меню, которое предлагает пользователю

на выбор один из нескольких возможных вариантов, например, «дешевый», «умеренный», «дорогой», «экстравагантный» и «непомерный». Вы можете расширить последовательность if else if else для обработки этих пяти альтернатив, но оператор C++ switch упрощает обработку выбора из большого списка. Ниже представлена общая форма оператора switch:
switch (целочисленное-выражение)
{
case метка 1 : оператор(ы)
case метка 2 : оператор(ы)

default : оператор (ы)
}
В данном случае слово case означает не «ящик», как наивно полагают некоторые, а «в случае».
Слайд 10

Оператор Switch Оператор switch действует подобно маршрутизатору, который сообщает компилятору, какую

Оператор Switch

Оператор switch действует подобно маршрутизатору, который сообщает компилятору, какую строку

кода выполнять следующей. По достижении оператора switch программа переходит к строке, которая помечена значением, соответствующим текущему значению целочисленное-выражение. Например, если целочисленное-выражение имеет значение 4, то программа переходит к строке с меткой case 4:
Как следует из названия, выражение целочисленное-выражение должно быть целочисленным. Также каждая метка должна быть целым константным выражением. Чаще всего метки бывают константами типа char или int, такими как 1 или 'q', либо же перечислителями. Если целочисленное-выражение не соответствует ни одной метке, программа переходит к метке default. Метка default не обязательна. Если она опущена, а соответствия не найдено, программа переходит к оператору, следующему за switch (рис. 4.1.).
Слайд 11

Оператор Switch Оператор switch в C++ отличается от аналогичных операторов в

Оператор Switch

Оператор switch в C++ отличается от аналогичных операторов в других

языках, например, Pascal, в одном очень важном отношении. Каждая метка case в C++ работает только как метка строки, а не граница между выборами.
То есть после того, как программа перейдет на определенную строку в switch, она последовательно выполнит все операторы, следующие за этой строкой внутри switch, если только вы явно не направите ее в другое место. Выполнение не останавливается автоматически на следующем case. Чтобы прекратить выполнение в конце определенной группы операторов, вы должны использовать оператор break. Это передаст управление за пределы блока switch.
Слайд 12

ЦИКЛЫ В C++. Цикл for Обстоятельства часто требуют от программ выполнения

ЦИКЛЫ В C++. Цикл for

Обстоятельства часто требуют от программ выполнения повторяющихся

задач, таких как сложение элементов массивов один за другим или 20-кратная распечатка похвалы за продуктивность. Цикл for облегчает выполнение задач подобного рода.
Если мы знаем точное количество действий (итераций) цикла, то можем использовать цикл for. Синтаксис его выглядит примерно так:
for (действие до начала цикла; условие продолжения цикла; действия в конце каждой итерации цикла)
{инструкция цикла 1; инструкция цикла 2; … инструкция цикла N; }
Итерацией цикла называется один проход этого цикла.
Обычно оператор выглядит так:
for (счетчик = значение; счетчик < значение; шаг цикла) {тело цикла }
Счетчик цикла — это переменная, в которой хранится количество проходов данного цикла. Описание синтаксиса следующее.
1. Сначала присваивается первоначальное значение счетчику, после чего ставится точка с запятой.
2. Затем задается конечное значение счетчика цикла. После того, как значение счетчика достигнет указанного предела, цикл завершится. Снова ставим точку с запятой.
3. Задаем шаг цикла. Шаг цикла — это значение, на которое будет увеличиваться или уменьшаться счетчик цикла при каждом проходе.
Слайд 13

Цикл for Пример кода Напишем программу, которая будет считать сумму всех

Цикл for

Пример кода
Напишем программу, которая будет считать сумму всех чисел от

1 до 1000.
#include
using namespace std;
Int main() {
int i; // счетчик цикла
int sum = 0; // сумма чисел от 1 до 1000.
set locale(0, "");
for (i = 1; i <= 1000; i++) // задаем начальное значение 1, конечное 1000 и задаем шаг цикла - 1.
{
sum = sum + i;
}
cout<<"Сумма чисел от 1 до 1000 = "<return 0;
}
Слайд 14

Цикл for Если мы скомпилируем этот код и запустим программу, то

Цикл for

Если мы скомпилируем этот код и запустим программу, то она

покажет нам ответ: 500500. Это и есть сумма всех целых чисел от 1 до 1000. Если считать это вручную, понадобится очень много времени и сил. Цикл выполнил всю рутинную работу за нас.
Заметьте, что конечное значение счетчика я задала нестрогим неравенством (<= — меньше либо равно), поскольку, если бы я поставила знак меньше, то цикл произвел бы 999 итераций, т.е. на одну меньше, чем требуется. Это довольно важный момент, т.к. здесь новички часто допускают ошибки, особенно при работе с массивами. Значение шага цикла я задала равное единице. i++ — это тоже самое, что и i = i + 1.
В теле цикла, при каждом проходе программа увеличивает значение переменной sum на i. Еще один очень важный момент — в начале программы я присвоила переменной sum значение нуля. Если бы я этого не сделала, программа вылетела вы в сегфолт. При объявлении переменной без ее инициализации эта переменная будет хранить «мусор».
Естественно, к мусору мы ничего прибавить не можем. Некоторые компиляторы инициализирует переменную нулем при ее объявлении.
Слайд 15

Сегфолт Ошибка сегментации (англ. Segmentation fault, сокр. segfault, жарг. сегфолт) —

Сегфолт

Ошибка сегментации (англ. Segmentation fault, сокр. segfault, жарг. сегфолт) — ошибка программного обеспечения, возникающая при попытке обращения

к недоступным для записи участкам памяти, либо при попытке изменить память запрещённым способом.
Условия, при которых происходят нарушения сегментации, и способы их проявления зависят от операционной системы.
Ещё один способ вызвать ошибку сегментации заключается в том, чтобы вызвать функцию main() рекурсивно, что приведёт к переполнению стека:
int main()
{
main();
}
Ошибка сегментации возникнет, если при использовании массивов случайно указать в качестве размера массива неинициализированную переменную:
int main()
{
const int nmax = 10;
int i, n, a[n];
}
Слайд 16

Операции инкремента и декремента Язык C++ снабжен несколькими операциями, которые часто

Операции инкремента и декремента

Язык C++ снабжен несколькими операциями, которые часто используются

в циклах; давайте потратим немного времени на их изучение. Вы уже видели одну из них - операцию инкремента (++), которая получила отражение в самом названии C++. Есть также операция декремента (--). Эти операции выполняют два чрезвычайно часто встречающихся действия в циклах: увеличивают и уменьшают на единицу значение счетчика цикла. Однако к тому, что вы уже знаете о них, есть что добавить. Каждая из них имеет два варианта. Префиксная версия операции указывается перед операндом, как в ++х. Постфиксная версия следует после операнда, как в х++. Эти две версии имеют один и тот же эффект для операнда, но отличаются в контексте применения. Все похоже на получение оплаты за стрижку газона авансом или после завершения работы: оба метода имеют один и тот же конечный результат для вашего бумажника, но отличаются тем, в какой момент деньги в него добавляются. В листинге ниже демонстрируется разница на примере операции инкремента.
Слайд 17

Операции инкремента и декремента Результат выполнения этой программы показан ниже:

Операции инкремента и декремента

Результат выполнения этой программы показан ниже:

Слайд 18

Операции инкремента и декремента Грубо говоря, нотация а++ означает "использовать текущее

Операции инкремента и декремента

Грубо говоря, нотация а++ означает "использовать текущее значение

а при вычислении выражения, затем увеличить а на единицу". Аналогично нотация ++а означает "сначала увеличить значение а на единицу, затем использовать новое значение при вычислении выражения". Например, мы имеем следующие отношения:
int х = 5;
int у = ++х; // изменить х, затем присвоить его у
// у равно 6, х равно 6
int z = 5;
int у = z++; // присвоить у, затем изменить z
//у равно 5, z равно 6
Слайд 19

Операции инкремента и декремента Операции инкремента и декремента представляют собой простой

Операции инкремента и декремента

Операции инкремента и декремента представляют собой простой удобный

способ решения часто возникающей задачи увеличения или уменьшения значений на единицу. Операции инкремента и декремента — симпатичные и компактные, но не стоит поддаваться соблазну и применять их к одному и тому же значению более одного раза в одном и том же операторе. Проблема в том, что при этом правила "использовать и изменить" и "изменить и использовать" становятся неоднозначными. То есть, следующий оператор в различных системах может дать совершенно разные результаты:
х = 2 * х++ * (3 - ++х) ; //не поступайте так
В C++ поведение операторов подобного рода не определено.
Слайд 20

Цикл While Когда мы не знаем, сколько итераций должен произвести цикл,

Цикл While

Когда мы не знаем, сколько итераций должен произвести цикл, нам

нужны циклы while или do...while. Синтаксис цикла while в C++ выглядит следующим образом.
while (Условие) {Тело цикла;}
Данный цикл будет выполняться, пока условие, указанное в круглых скобках, является истиной. Решим задачу о сумме рядя с помощью цикла while. Хотя здесь мы точно знаем, сколько итераций должен выполнить цикл, очень часто бывают ситуации, когда это значение неизвестно.
Ниже приведен исходный код программы, считающей сумму всех целых чисел от 1 до 1000.
Слайд 21

Цикл While После компиляции программа выдаст результат, аналогичный результату работы предыдущей

Цикл While

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

Но поясним несколько важных моментов. Я задала строгое неравенство в условии цикла и инициализировала счетчик i нулем, так как в цикле while происходит на одну итерацию больше, поэтому он будет выполняться до тех пор, пока значение счетчика не перестает удовлетворять условию, но данная итерация все равно выполнится. Если бы мы поставили нестрогое неравенство, то цикл бы закончился, когда переменная i стала бы равна 1001 и выполнилось бы на одну итерацию больше.
Теперь давайте рассмотрим по порядку исходный код нашей программы. Сначала мы инициализируем счетчик цикла и переменную, хранящую сумму чисел.
В данном случае мы обязательно должны присвоить счетчику цикла какое-либо значение. В предыдущей программе мы это значение присваивали внутри цикла for, здесь же, если мы не инициализируем счетчик цикла, то в него попадет «мусор» и компилятор, в лучшем случае, выдаст нам ошибку, а в худшем, если программа соберется — дефолт практически неизбежен. Дефолт буквально – невыполнение договора.
Слайд 22

Цикл While Затем мы описываем условие цикла — «пока переменная i

Цикл While

Затем мы описываем условие цикла — «пока переменная i меньше

1000 — выполняй цикл». При каждой итерации цикла значение переменной-счетчика i увеличивается на единицу внутри цикла.
Когда выполнится 1000 итераций цикла, счетчик станет равным 999 и следующая итерация уже не выполнится, поскольку 1000 не меньше 1000. Выражение sum += i является укороченной записью sum = sum + i.
После окончания выполнения цикла выводим сообщение с ответом.
Слайд 23

Цикл do while Цикл do while очень похож на цикл while.

Цикл do while

Цикл do while очень похож на цикл while. Единственное

их различие в том, что при выполнении цикла do while один проход цикла будет выполнен независимо от условия. Приведу решение задачи на поиск суммы чисел от 1 до 1000, с применением цикла do while. Принципиального отличия нет, но если присвоить переменной i значение, большее, чем 1000, то цикл все равно выполнит хотя бы один проход.
Слайд 24

МАССИВЫ в С++ Теперь мы с поговорим о массивах. Вы уже

МАССИВЫ в С++

Теперь мы с поговорим о массивах. Вы уже знаете,

что переменная — это ячейка в памяти компьютера, где может храниться одно единственное значение. 
Массив — это область памяти, где могут последовательно храниться несколько значений.
Слайд 25

МАССИВЫ в С++ Массив — это структура данных, которая содержит множество

МАССИВЫ в С++

Массив — это структура данных, которая содержит множество значений,

относящихся к одному и тому же типу. Например, массив может содержать 60 значений типа int, которые представляют информацию об объемах продаж за 5 лет, 12 значений типа short, представляющих количество дней в каждом месяце, или 365 значений типа float, которые указывают ежедневные расходы на питание в течение года. Каждое значение сохраняется в отдельном элементе массива, и компьютер хранит все элементы массива в памяти последовательно — друг за другом.
Слайд 26

Массивы в С++ Для создания массива используется оператор объявления. Объявление массива

Массивы в С++

Для создания массива используется оператор объявления. Объявление массива должно

описывать три аспекта:
• тип значений каждого элемента;
• имя массива;
• количество элементов в массиве.
В C++ это достигается модификацией объявления простой переменной, к которому добавляются квадратные скобки, содержащие внутри количество элементов. Например, следующее объявление создает массив по имени months, имеющий 12 элементов, каждый из которых может хранить одно значение типа short:
short months[12]; // создает массив из 12 элементов типа short
Слайд 27

Массивы в С++ Большая часть пользы от массивов определяется тем фактом,

Массивы в С++

Большая часть пользы от массивов определяется тем фактом, что

к его элементам можно обращаться индивидуально. Способ, который позволяет это делать, заключается в использовании индекса для нумерации элементов. Нумерация массивов в C++ начинается с нуля. (Это является обязательным — вы должны начинать с нуля. Это особенно важно запомнить программистам, ранее работавшим на языках Pascal и BASIC.) Для указания элемента массива в C++ используется обозначение с квадратными скобками и индексом между ними. Например, months [0] — это первый элемент массива months, a months [11] — его последний элемент. Обратите внимание, что индекс последнего элемента на единицу меньше, чем размер массива (рис. 7.1). Таким образом, объявление массива позволяет создавать множество переменных в одном объявлении, и вы затем можете использовать индекс для идентификации и доступа к индивидуальным элементам.
Слайд 28

Массивы в С++

Массивы в С++

Слайд 29

Элементы массива Каждая из переменных в массиве называется элементом. Элементы не

Элементы массива

Каждая из переменных в массиве называется элементом. Элементы не имеют

своих собственных уникальных имен. Вместо этого для доступа к ним используется имя массива вместе с оператором индекса [] и параметром, который называется индексом, и который сообщает компилятору, какой элемент мы хотим выбрать. Этот процесс называется индексированием массива.
В сущности, каждый элемент — это переменная, которую можно трактовать как простую переменную.
Важно: в отличие от повседневной жизни, отсчет в программировании в С++ всегда начинается с 0, а не с 1. Для массива длиной N элементы массива будут пронумерованы от 0 до N-1. Это называется диапазоном массива.
Слайд 30

Элементы массива Рассмотрим случай, когда нужно записать результаты тестов 30 студентов

Элементы массива

Рассмотрим случай, когда нужно записать результаты тестов 30 студентов в

классе. Без использования массива нам придется выделить почти 30 одинаковых переменных!
// Выделяем 30 целочисленных переменных (каждая с разным именем)
int testResultStudent1;
int testResultStudent2;
int testResultStudent3;
// ...
int testResultStudent30;
С использованием массива всё гораздо проще. Следующая строчка эквивалентна коду выше:
int testResult[30]; // выделяем 30 целочисленных переменных, используя фиксированный массив
Слайд 31

Объявление массива Для создания массива используется оператор объявления. Объявление массива должно

Объявление массива

Для создания массива используется оператор объявления. Объявление массива должно описывать

три аспекта:
• тип значений каждого элемента;
• имя массива;
• количество элементов в массиве.
В C++ это достигается модификацией объявления простой переменной, к которому добавляются квадратные скобки, содержащие внутри количество элементов. Например, следующее объявление создает массив по имени months, имеющий 12 элементов, каждый из которых может хранить одно значение типа short:
short months[12]; // создает массив из 12 элементов типа short
Слайд 32

Объявление массива Итак, в объявлении переменной массива мы используем квадратные скобки

Объявление массива

Итак, в объявлении переменной массива мы используем квадратные скобки [], чтобы

сообщить компилятору, что это переменная массива (а не обычная переменная), а в скобках — количество выделяемых элементов (это называется длиной или размером массива).
В примере, приведенном выше, мы объявили фиксированный массив с именем testResult и длиной 30. Фиксированный массив (или «массив фиксированной длины») представляет собой массив, размер которого известен во время компиляции. При создании testResult, компилятор выделит 30 целочисленных переменных.
Слайд 33

Объявление массива Так выглядит общая форма объявления массива: имя Типа имя

Объявление массива

Так выглядит общая форма объявления массива:
имя Типа имя Массива[размер

Маccива];
Выражение размер Массива, представляющее количество элементов, должно быть целочисленной константой, такой как 10, значением const либо константным выражением вроде 8 * sizeof(int), в котором все значения известны на момент компиляции. В частности, размер Массива не может быть переменной, значение которой устанавливается во время выполнения программы.
Слайд 34

Объявление переменной массива В вышеприведенном примере первым элементом в нашем массиве

Объявление переменной массива

В вышеприведенном примере первым элементом в нашем массиве является

testResult[0], второй — testResult[1], десятый — testResult[9], последний — testResult[29]. Хорошо, что уже не нужно отслеживать и помнить кучу разных (хоть и похожих) имен переменных — для доступа к разным элементам нужно изменить только индекс.
Слайд 35

Правила инициализации массивов в С++ В C++ существует несколько правил, касающихся

Правила инициализации массивов в С++

В C++ существует несколько правил, касающихся инициализации

массивов. Они ограничивают, когда вы можете ее осуществлять, и определяют, что случится, если количество элементов массива не соответствует количеству элементов инициализатора. Давайте рассмотрим эти правила.
Вы можете использовать инициализацию только при объявлении массива. Ее нельзя выполнить позже, и нельзя присваивать один массив другому:
Int cards [4] = {3, 6, 8, 10}; // все в порядке
Int hand[4]; // все в порядке
hand[4] = {5, 6, 7, 9}; //не допускается
hand = cards; // не допускается
Слайд 36

Правила инициализации массивов в С++ Однако можно использовать индексы и присваивать

Правила инициализации массивов в С++

Однако можно использовать индексы и присваивать значения

элементам массива индивидуально.
При инициализации массива можно указывать меньше значений, чем в массиве объявлено элементов. Например, следующий оператор инициализирует только первые два элемента массива hotelTips:
float hotelTips[5] = {5.0, 2.5};
Если вы инициализируете массив частично, то компилятор присваивает остальным элементом нулевые значения. Это значит, что инициализировать весь массив нулями очень легко — для этого просто нужно явно инициализировать нулем его первый элемент, а инициализацию остальных элементов поручить компилятору:
long totals[500] = {0};
Слайд 37

Правила инициализации массивов в С++ Следует отметить, что в случае инициализации

Правила инициализации массивов в С++

Следует отметить, что в случае инициализации массива

с применением {1} вместо {0} только первый элемент будет установлен в 1; остальные по-прежнему получат значение 0.
Если при инициализации массива оставить квадратные скобки пустыми, то компилятор C++ самостоятельно пересчитает элементы. Предположим, например, что есть следующее объявление:
short things [] = {1, 5, 3, 8};
Компилятор сделает things массивом из пяти элементов.
Слайд 38

Пример программы с использованием массива Пример программы с использованием массива. Здесь

Пример программы с использованием массива

Пример программы с использованием массива. Здесь мы

можем наблюдать как определение, так и индексирование массива.

Результат выполнения программы:
The lowest number is 3
The sum of the first 5 numbers is 29

Слайд 39

Типы данных и массивы Массив может быть любого типа данных. Например,

Типы данных и массивы

Массив может быть любого типа данных.
Например, объявляем

массив типа double:
#include
int main()
{
    double array[3]; // выделяем 3 переменные типа double
    array[0] = 3.5;
    array[1] = 2.4;
    array[2] = 3.4;
std::cout << "The average is " << (array[0] + array[1] + array[2]) / 3 << "\n";
return 0;
}
Результат выполнения программы:
The average is 3.1
Слайд 40

Пространство имен Пространство имён (англ. namespace) — некоторое множество, под которым

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

Пространство имён (англ. namespace) — некоторое множество, под которым подразумевается модель, абстрактное хранилище, созданное для логической группировки уникальных идентификаторов (то

есть имён).
Идентификатор, определённый в пространстве имён, ассоциируется с этим пространством. Один и тот же идентификатор может быть независимо определён в нескольких пространствах. Таким образом, значение, связанное с идентификатором, определённым в одном пространстве имён, может иметь (или не иметь) такое же значение, как и такой же идентификатор, определённый в другом пространстве. Языки с поддержкой пространств имён определяют правила, указывающие, к какому пространству имён принадлежит идентификатор (то есть его определение).
Например, Андрей работает в компании X, а ID (сокр. от англ. Identifier — идентификатор) его как работника равен 123. Олег работает в компании Y, а его ID также равен 123. Единственное (с точки зрения некой системы учёта), благодаря чему Андрей и Олег могут быть различимы при совпадающих ID, это их принадлежность к разным компаниям. Различие компаний в этом случае представляет собой систему различных пространств имён (одна компания — одно пространство).
Слайд 41

Пространство имен В больших базах данных могут существовать сотни и тысячи

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

В больших базах данных могут существовать сотни и тысячи идентификаторов.

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

Типы данных и массивы Возьмем группу студентов из десяти человек. У

Типы данных и массивы

Возьмем группу студентов из десяти человек. У каждого

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

Индексы элементов массива В языке C++ индексы массивов всегда должны быть

Индексы элементов массива

В языке C++ индексы массивов всегда должны быть интервального

типа данных (т.е. типа char, short, int, long, bool и т.д.). Эти индексы могут быть либо константными значениями, либо неконстантными значениями.
Пример инициализации массива
string students[10] = {
"Иванов", "Петров", "Сидоров",
"Ахмедов", "Ерошкин", "Выхин",
"Андеев", "Вин Дизель", "Картошкин", "Пупкин"
};
Слайд 44

Описание синтаксиса Массив создается почти так же, как и обычная переменная.

Описание синтаксиса

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

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

Описание синтаксиса Попробуем вывести наш массив на экран с помощью cout.

Описание синтаксиса

Попробуем вывести наш массив на экран с помощью cout.
#include
#include


int main()
{
std::string students[10] =
{“Иванов”, ”Петров”, ”Сидоров”, “Ахмедов”,
”Ерошкин”, “Выхин”, ”Андреев”,
”Вин Дизель”, ”Картошкин”, ”Пупкин”
}
std::cout< return 0;
}
Слайд 46

Описание синтаксиса Скомпилируйте этот код и посмотрите, на результат работы программы.

Описание синтаксиса

Скомпилируйте этот код и посмотрите, на результат работы программы. Готово?

А теперь запустите программу еще раз и сравните с предыдущим результатом. В моей операционной системе вывод был следующим:
первый вывод: 0x7ffff8b85820
второй вывод: 0x7fff7a335f90
третий вывод: 0x7ffff847eb40
Мы видим, что выводится адрес этого массива в оперативной памяти, а никакие не «Иванов» и «Петров».
Дело в том, что при создании переменной компилятор выделяет ей определенное место в памяти. Если мы объявляем переменную типа int, то на машинном уровне она описывается двумя параметрами — ее адресом и размером хранимых данных.
Слайд 47

Описание синтаксиса Скомпилируйте этот код и посмотрите на результат работы еще

Описание синтаксиса

Скомпилируйте этот код и посмотрите на результат работы еще раз.

Массивы в памяти хранятся таким же образом. Массив типа int из 10 элементов описывается с помощью адреса его первого элемента и количества байт, которое может вместить этот массив. Если для хранения одного целого числа выделяется 4 байта, то для массива из десяти целых чисел будет выделено 40 байт.
Так почему же, при повторном запуске программы, адреса различаются? Это сделано для защиты от атак переполнения буфера. Такая технология называется рандомизацией адресного пространства и реализована в большинстве популярных операционных систем.
Слайд 48

Рандомизация адресного пространства ASLR (англ. address space layout randomization — «рандомизация

Рандомизация адресного пространства

ASLR (англ. address space layout randomization — «рандомизация размещения адресного пространства»).
Рандомизация размещения

адресного пространства — это технология, применяемая в операционных системах, при использовании которой случайным образом изменяется расположение в адресном пространстве процесса  структур данных.
Эта технология создана для усложнения использования хакерами нескольких типов уязвимостей. Например, если при помощи переполнения буфера или другим методом атакующий получит возможность передать управление по произвольному адресу, ему нужно будет угадать, по какому именно адресу расположены данные.
В приведённых примерах от атакующего скрыты конкретные адреса, и, если не удастся угадать правильный адрес, программа, скорее всего, аварийно завершится, тем самым лишив атакующего возможности повторной атаки и привлекая внимание системного администратора.
Таким образом, ASLR – это алгоритм назначения различным компонентам программы случайных адресов в пространстве памяти. ASLR используется в операционных системах для снижения риска эксплуатации уязвимостей, основанных на доступе к определенным ячейкам памяти, таких как переполнение буфера. Рандомизация адресного пространства затрудняет определение злоумышленником позиции конкретного блока целевой программы в ОЗУ и уменьшает вероятность успешной атаки.
Слайд 49

Описание синтаксиса Попробуем вывести первый элемент массива – фамилию студента Иванова.

Описание синтаксиса

Попробуем вывести первый элемент массива – фамилию студента Иванова.
#include
#include


int main()
{
std::string students[10] =
{“Иванов”, ”Петров”, ”Сидоров”, “Ахмедов”,
”Ерошкин”, “Выхин”, ”Андреев”,
”Вин Дизель”, ”Картошкин”, ”Пупкин”
}
std::cout<return 0;
}
Слайд 50

Описание синтаксиса Смотрим, компилируем, запускаем. Убедились, что вывелся именно «Иванов». Заметьте,

Описание синтаксиса

Смотрим, компилируем, запускаем. Убедились, что вывелся именно «Иванов». Заметьте, что

нумерация элементов массива в C++ начинается с нуля. Следовательно, фамилия первого студента находится в students[0], а фамилия последнего — в students[9].
Во многих языках программирования нумерация элементов массива также начинается с нуля.
Попробуем вывести список всех студентов. Но сначала подумаем, а что если бы вместо группы из десяти студентов, была бы кафедра их ста, факультет из тысячи, или даже весь университет? Ну не будем же мы писать десятки тысяч строк с cout?
Конечно же нет! Мы будем использовать циклы.
Слайд 51

Вывод элементов массива через цикл #include #include int main() { std::string

Вывод элементов массива через цикл

#include
#include
int main()
{
std::string students[10] =


{“Иванов”, ”Петров”, ”Сидоров”, “Ахмедов”,
”Ерошкин”, “Выхин”, ”Андреев”,
”Вин Дизель”, ”Картошкин”, ”Чубайс”
}
for (int i=0;i<10;i++)
{
std::cout< }
return 0;
}
Слайд 52

Вывод элементов массива через цикл Если бы нам пришлось выводить массив

Вывод элементов массива через цикл

Если бы нам пришлось выводить массив из

нескольких тысяч фамилий, то мы бы просто увеличили конечное значение счетчика цикла — строку for (...; i < 10; ...) заменили на for (...; i < 10000; ...).
Заметьте, что счетчик нашего цикла начинается с нуля, а заканчивается девяткой. Если вместо оператора строгого неравенства — i < 10 использовать оператор «меньше, либо равно» — i <= 10, то на последней итерации программа обратится к несуществующему элементу массива — students[10]. Это может привести к ошибкам сегментации и аварийному завершению программы. Будьте внимательны — подобные ошибки бывает сложно отловить.
Массив, как и любую переменную можно не заполнять значениями при объявлении.
Слайд 53

Объявление массива без инициализации string students[10]; // или string teachers[5]; Элементы

Объявление массива без инициализации

string students[10];
// или
string teachers[5];
Элементы такого массива обычно содержат

в себе «мусор» из выделенной, но еще не инициализированной, памяти. Некоторые компиляторы заполняют все элементы массива нулями при его создании.
При создании статического массива, для указания его размера может использоваться только константа. Размер выделяемой памяти определяется на этапе компиляции и не может изменяться в процессе выполнения.
int n;
cin>>n;
String students[n]; /*Неверно*/
Выделение памяти в процессе выполнения возможно при работе с динамическими массивами. Но о них немного позже.
Слайд 54

Заполнение массива с клавиатуры Заполним с клавиатуры пустой массив из 10

Заполнение массива с клавиатуры

Заполним с клавиатуры пустой массив из 10 элементов.
#include


#include
using std::cout;
using std::cin;
using std::endl;
int main()
{
int arr[10];
// Заполняем массив с клавиатуры
for (int i-0;i<10;i++)
{
cout<<“[“< cin>>arr[i];
}
Слайд 55

Заполнение массива с клавиатуры // И выводим заполненный массив cout for

Заполнение массива с клавиатуры

// И выводим заполненный массив
cout<<“\nВаш массив:”;
for

(int i=0;i<10;++i)
{
cout< }
cout<return 0;
}
Скомпилируем эту программу и проверим ее работу.
Слайд 56

Заполнение массива с клавиатуры

Заполнение массива с клавиатуры

Слайд 57

Задачи с решениями Задача 1. Найдите сумму отрицательных элементов массива. int

Задачи с решениями

Задача 1. Найдите сумму отрицательных элементов массива.
int sum=0;
for (int

i=0; i{
   if (a[i]<0)
   {
      sum+=a[i];
   }
}
if (!sum)
{
   cout<<"no numbers < 0";
}
else
{
  cout<<"sum = "<}
Слайд 58

Задачи с решениями Задача 2. Найдите произведение элементов массива с нечетными

Задачи с решениями

Задача 2. Найдите произведение элементов массива с нечетными номерами.
int

p=1;
for (int i=1; i{
   p*=a[i];
}
cout<<"answer: "<
Слайд 59

Задачи с решениями Задача 3. Найдите наибольший элемент массива. int max=0;

Задачи с решениями

Задача 3. Найдите наибольший элемент массива.
int max=0;
for (int i=1;

imax)
   max=a[i];
}
cout<<"max: "<
Слайд 60

Задачи с решениями Задача 4. Найдите наименьший четный элемент массива. Если

Задачи с решениями

Задача 4. Найдите наименьший четный элемент массива. Если такого

нет, то выведите первый элемент.
int imin=-1;
for (int i=0; i if ((!(a[i]%2) && (imin==-1 || a[imin]>a[i]))
imin=i;
}
if (imin==-1)
cout<else
cout<
Слайд 61

Задачи с решениями Задача 5. Преобразовать массив так, чтобы сначала шли

Задачи с решениями

Задача 5. Преобразовать массив так, чтобы сначала шли нулевые

элементы, а затем все остальные.
int i1=0, i2=n-1;
while (i1{
// www.itmathrepetitor.ru
while (i1 < i2 && !a[i1])
i1++;
while (i2 > i1 && a[i2])
i2--;
if (i1 < i2)
{
int tmp=a[i1];
a[i1]=a[i2];
a[i2]=tmp;
}
i1++;
i2--;
}
Слайд 62

Задачи с решениями Задача 6. Найдите сумму номеров минимального и максимального

Задачи с решениями

Задача 6. Найдите сумму номеров минимального и максимального элементов

массива.
int imax=0, imin=0;
for (int i=1; i < n; i++) {
if (a[i]>a[imax])
imax=i;
if (a[i] imin=i;
}
cout<<"answer: "<
Слайд 63

Задачи с решениями Задача 7. Найдите минимальный по модулю элемент массива.

Задачи с решениями

Задача 7. Найдите минимальный по модулю элемент массива.
int min=abs(a[0]);
for

(int i = 1; i < n; i++) {
if (min>abs(a[i]))
min=a[i];
}
cout<<"abs min: "<
Слайд 64

МНОГОМЕРНЫЕ МАССИВЫ С++ позволяет создавать многомерные массивы. Простейшим видом многомерного массива

МНОГОМЕРНЫЕ МАССИВЫ

С++ позволяет создавать многомерные массивы. Простейшим видом многомерного массива является

двумерный массив. Двумерный массив - это массив одномерных массивов. Двумерный массив объявляется следующим образом:
тип имя_массива[количество строк][количество столбцов];
Следовательно, для объявления двумерного массива целых с размером 10 на 20 следует написать:
int d[10] [20];
Посмотрим внимательно на это объявление. В противоположность другим компьютерным языкам, где размерности массива отделяются запятой, С++ помещает каждую размерность в отдельные скобки.
Для доступа к элементу с индексами 3, 5 массива d следует использовать запись d[3] [5]
Слайд 65

Многомерные массивы С++ позволяет создавать многомерные массивы. Простейшим видом многомерного массива

Многомерные массивы

С++ позволяет создавать многомерные массивы. Простейшим видом многомерного массива является

двумерный массив. Двумерный массив - это массив одномерных массивов. Двумерный массив объявляется следующим образом:
тип имя_массива[количество строк][количество столбцов];
Следовательно, для объявления двумерного массива целых с размером 10 на 20 следует написать:
int d[10] [20];
Посмотрим внимательно на это объявление. В противоположность другим компьютерным языкам, где размерности массива отделяются запятой, С++ помещает каждую размерность в отдельные скобки.
Для доступа к элементу с индексами 3,5 массива d следует использовать запись d[3] [5]
Слайд 66

Многомерные массивы В C/C++ прямоугольный двумерный массив чисел реализует математическое понятие

Многомерные массивы

В C/C++ прямоугольный двумерный массив чисел реализует математическое понятие «матрица».

Однако, в общем случае, двумерный массив — понятие гораздо более широкое, чем матрица, поскольку он может быть и не прямоугольным, и не числовым.
Определение автоматических многомерных массивов почти полностью совпадает с определением одномерных, за исключением того, что вместо одного размера может быть указано несколько:
const unsigned int DIM1 = 3;
const unsigned int DIM2 = 5;
int ary[DIM1][DIM2];
В этом примере определяется двумерный массив из 3 строк по 5 значений типа int в каждой строке. Итого 15 значений типа int.
Слайд 67

Инициализация массива При статической (определяемой на этапе компиляции) инициализации значения элементов

Инициализация массива

При статической (определяемой на этапе компиляции) инициализации значения элементов массива

перечисляются в порядке указания размеров (индексов) в определении массива. Каждый уровень многомерного массива заключается в свою пару фигурных скобок:
const unsigned int DIM1 = 3;
const unsigned int DIM2 = 5;
int ary[DIM1][DIM2] = {
{ 1, 2, 3, 4, 5 },
{ 2, 4, 6, 8, 10 },
{ 3, 6, 9, 12, 15 }
};
В примере показана статическая инициализация прямоугольного массива. Весь список инициализирующих значений заключён в фигурные скобки. Значения для каждой из 3 строк заключены в свою пару из фигурных скобок, значения для каждого из 5 столбцов для каждой строки перечислены через запятую.
Слайд 68

Заполнение массива значениями Многомерный массив заполняется значениями с помощью вложенных циклов.

Заполнение массива значениями

Многомерный массив заполняется значениями с помощью вложенных циклов. Причём,

как правило, количество циклов совпадает с размерностью массива:
#include
#include
using namespace std;
const unsigned int DIM1 = 3;
const unsigned int DIM2 = 5;
int ary[DIM1][DIM2];
int main() {
for (int i = 0; i < DIM1; i++) {
for (int j = 0; j < DIM2; j++) {
ary[i][j] = (i + 1) * 10 + (j + 1);
}
}
// ...
Слайд 69

Заполнение массива значениями В этом примере каждому элементу массива присваивается значение,

Заполнение массива значениями

В этом примере каждому элементу массива присваивается значение, первая

цифра которого указывает номер строки, а вторая цифра — номер столбца для этого значения (нумерация с 1).
Слайд 70

Вывод значений элементов массива на консоль В продолжение предыдущего примера можно

Вывод значений элементов массива на консоль

В продолжение предыдущего примера можно написать:

for (int i = 0; i < DIM1; i++) {
for (int j = 0; j < DIM2; j++) {
cout << setw(4) << ary[i][j];
}
cout << endl;
}
return 0;
}
В результате получим следующий вывод на консоль:
11 12 13 14 15
21 22 23 24 25
31 32 33 34 35
Слайд 71

Формат вывода. Манипулятор setw setw задаёт разную ширину поля вывода строк

Формат вывода. Манипулятор setw

setw задаёт разную ширину поля вывода строк
Этот манипулятор

устанавливает ширину поля, равную w.
#include
#include
using namespace std;
int main()
{
long pop1=8425785, pop2=47, pop3=9761;
cout << setw(9) << "Город " << setw(12) << "Население " << endl
<< setw(9) << "Москва" << setw(12) << pop1 << endl
<< setw(9) << "Киров" << setw(12) << pop2 << endl
<< setw(9) << "Угрюмовка" << setw(12) << pop3 << endl;
return 0;
}
И результат его работы:
Город Население
Москва 8425785
Киров 47
Угрюмовка 9761
Слайд 72

Пример работы с трехмерным массивом Для трёхмерного массива можно написать код,

Пример работы с трехмерным массивом

Для трёхмерного массива можно написать код, использующий

те же приёмы:
#include
#include
using namespace std;
const unsigned int DIM1 = 3;
const unsigned int DIM2 = 5;
const unsigned int DIM3 = 2;
int ary[DIM1][DIM2][DIM3];
int main() {
for (int i = 0; i < DIM1; i++)
{
for (int j = 0; j < DIM2; j++)
{
Слайд 73

Пример работы с трехмерным массивом for (int k = 0; k

Пример работы с трехмерным массивом

for (int k = 0; k

< DIM3; k++)
{
ary[i][j][k] = (i + 1) * 100 + (j + 1) * 10 + (k + 1);
cout << setw(4) << ary[i][j][k];
}
cout << endl;
}
cout << endl;
}
return 0;
}
Здесь присваивание значения элементу массива и вывод на консоль происходят в одной группе циклов.
Слайд 74

ПЕРВОЕ ЗНАКОМСТВО С ДИНАМИЧЕСКИМИ МАССИВАМИ Фиксированные массивы обеспечивают простой способ выделения

ПЕРВОЕ ЗНАКОМСТВО С ДИНАМИЧЕСКИМИ МАССИВАМИ

Фиксированные массивы обеспечивают простой способ выделения

и использования нескольких переменных одного типа данных так как размер массива известен во время компиляции.
Поскольку массивам фиксированного размера память выделяется во время компиляции, то здесь мы имеем два ограничения:
1) массивы фиксированного размера не могут иметь длину, основанную на любом пользовательском вводе или другом значении, которое вычисляется во время выполнения программы;
2) фиксированные массивы имеют фиксированную длину, которую нельзя изменить.
Во многих случаях эти ограничения являются проблематичными. К счастью, C++ поддерживает еще один тип массивов, известный как динамический массив. Размер такого массива может быть установлен во время выполнения программы, и его можно изменить. Однако создание динамических массивов несколько сложнее фиксированных, поэтому мы поговорим об этом попозже.