Основы программирования на C++: различия между версиями
Ctrlalt (обсуждение | вклад) |
Ctrlalt (обсуждение | вклад) |
||
Строка 291: | Строка 291: | ||
} | } | ||
//Вывод: 0 1 2 3 5 6 7 9 | //Вывод: 0 1 2 3 5 6 7 9 | ||
=== Массивы === | |||
==== Объявление и использование массивов ==== | |||
Массив — несколько переменных одного типа, имеющих общее имя и различные индексы. Для обращения к ячейке массива требуется написать имя массива, а затем — индекс ячейки в квадратных скобках. | |||
int x; //одна переменная типа int, 4 байта | |||
int a[5]; //массив из 5 ячеек типа int, 20 байт | |||
Ячейки массива имеют индексы от 0 до (SIZE - 1), где SIZE — размер массива. | |||
int a[10]; //объявлены 10 ячеек: a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9] | |||
int b[100]; //объявлены 100 ячеек: от a[0] до a[99] | |||
С ячейками массива можно работать как с обычными переменными: | |||
int a[5]; | |||
a[0] = 100; | |||
a[1] = a[0] * 2; | |||
printf("%d", a[1]); //вывод: 200 | |||
При создании массива можно сразу задать ячейкам начальные значения (как и в случае с отдельными переменными). Если этого не сделать, массив изначально будет содержать случайные значения (мусор). | |||
int x; //x — отдельная переменная, содержит случайное значение (мусор) | |||
int y = 100; //y — отдельная переменная, содержит значение 100 | |||
int a[3]; //a — массив из 3 ячеек, которые содержат случайные значения (мусор) | |||
int b[3] = {100, 200, 300}; //b — массив из 3 ячеек, которые содержат значения 100, 200 и 300 | |||
==== Считывание и вывод массивов ==== | |||
Если определён массив из 5 ячеек, и значения ячеек вводятся с клавиатуры, можно использовать 5 операций scanf: | |||
int a[5]; | |||
scanf("%d", &a[0]); | |||
scanf("%d", &a[1]); | |||
scanf("%d", &a[2]); | |||
scanf("%d", &a[3]); | |||
scanf("%d", &a[4]); | |||
Но проще и правильнее в данном случае использовать цикл for: | |||
int a[5]; | |||
for (int i = 0; i < 5; i++) { | |||
scanf("%d", &a[i]); | |||
} | |||
<span style="color:red">Часто в задачах размер массива неизвестен заранее, и его также нужно вводить с клавиатуры. В этом случае нужно объявить массив на такое количество ячеек, которого заведомо хватит во всех случаях (как правило, узнать это количество можно из ограничений в разделе «Входные данные»), а затем сделать отдельную переменную size и использовать её.</span> | |||
int size; //объявляем переменную для фактического размера массива | |||
scanf("%d", &size); //считываем размер массива | |||
int a[100010]; //объявляем массив такой величины, чтобы его хватило для всех тестов | |||
for (int i = 0; i < size; i++) { //считываем столько ячеек массива, сколько указано в size | |||
scanf("%d", &a[i]); | |||
} | |||
Аналогичным образом выполняется вывод ячеек массива на печать: | |||
for (int i = 0; i < size; i++) { | |||
printf("%d ", a[i]); | |||
} |
Версия от 12:02, 25 декабря 2017
В любой непонятной ситуации
Пишите преподавателю:
- Кашичкин Максим Олегович — vk.com/m.kashichkin
- Кондратьев Евгений Валерьевич — teach.ekon@yandex.ru
- Фолунин Владимир Александрович — v.folunin@gmail.com
Не забудьте указать тему, представиться и обстоятельно описать свою проблему.
Дневники групп
Подготовка к работе
Установка среды разработки
- Visual Studio 2017 Community (для Windows 7 — Windows 10)
- Выберите только вариант «Разработка классических приложений на C++»
- Visual Studio 2010 (для Windows XP, но также рекомендуется, если вы не хотите выкачивать большие установочные файлы)
Создание проекта в Visual Studio
Создаём проект:
Меню Файл (File) → Создать (New) → Проект... (Project...) → слева выбираем Visual C++ → справа выбираем Пустой проект (Empty Project) → вводим имя проекта → OK.
Добавляем в проект новый файл:
Меню Проект (Project) → Добавить новый элемент... (Add New Item...) → Файл C++ (C++ File) → вводим имя файла → Добавить (Add).
Решение проблем
- Visual Studio не позволяет мне использовать scanf
- Меню Проект (Project) → Свойства (Properties) → C/C++ → Проверки SDL (SDL Checks) → выбрать значение Нет (No) → OK.
- Другой способ: скопировать в начало программы строку #define _CRT_SECURE_NO_WARNINGS
- При запуске появляется окно Следующий проект устарел. Выполнить его сборку? (This project is out of date. Would you like to build it?)
- Поставьте галочку Больше не выводить это окно (Do not show this dialog again) и нажмите кнопку Да (Yes).
- Если программа содержит ошибки, при запуске появляется окно Возникли ошибки сборки. Продолжить и запустить последний успешно построенный вариант? (There were build errors. Would you like to continue and run the last successful build?)
- Поставьте галочку Больше не выводить это окно (Do not show this dialog again) и нажмите кнопку Нет (No).
- Где посмотреть, какие у меня ошибки?
- Меню Вид (View) → Список ошибок (Error List). В более старых версиях: View → Other Windows → Error List.
Вспомогательные материалы к занятиям
Введение. Переменные. Ввод-вывод
Минимальная программа на C++
int main() { }
В любой программе всегда должна быть функция main. Фигурные скобки обозначают начало и конец функции, все команды записываются внутри.
До функции main, в самом начале файла, обычно указываются директивы #include (например #include <stdio.h>).
Использование переменных
Чтобы добавить в программу переменную, укажите её тип, название и, если необходимо, начальное значение.
int radius = 100; //целое число radius со значением 100 double circleArea = 3.14 * radius * radius; //дробное число circleArea, значение вычисляется по формуле
Переменные могут менять своё значение:
radius = radius * 2; //радиус увеличился в 2 раза
Часто используемые типы данных:
int | целые числа | от -231 до 231-1 (примерно от -2·109 до 2·109) | 4 байта |
long long | большие целые числа | от -263 до 263-1 (примерно от -9·1018 до 9·1018) | 8 байт |
double | дробные числа | точность 15-16 десятичных цифр | 8 байт |
Вывод при помощи функции printf
Функция printf используется для печати на экране. Для использования printf нужно подключить stdio.h (#include <stdio.h>).
printf выводит только то, что указано в кавычках. Для вывода перевода строки используется специальный символ \n.
printf("Hello World!\n"); //выводит Hello World! printf("My name\nis Vasya."); //выводит My name, а затем на новой строке is Vasya.
printf может выводить переменные и значения выражений, но для этого в строке с кавычками нужно указать места («окошечки»), куда следует подставлять значения. Места указываются при помощи спецификаторов.
int salary = 100; printf("Your salary is %d $.\n", salary); //выводит Your salary is 100 $. printf("Next year you'll have %.2lf $.", salary * 1.5); //выводит Next year you'll have 150.00 $.
Часто используемые спецификаторы:
%d | int |
%lld | long long |
%lf | double |
%.Xlf | double, X знаков после точки (например, %.2lf — 2 знака после точки) |
printf может выводить несколько значений:
printf("P:%d S:%d", 2 * (3 + 4), 3 * 4); //выводит P:14 S:12
Ввод при помощи функции scanf
Функция scanf используется для ввода с клавиатуры. Для использования scanf нужно подключить stdio.h (#include <stdio.h>).
scanf похож на printf, но перед каждой переменной следует ставить амперсанд &:
int age; scanf("%d", &age); //значение переменной age вводится с клавиатуры
scanf может вводить несколько значений:
int time; double speed; scanf("%d%lf", &time, &speed); //значения переменных time и speed вводятся с клавиатуры
Условия
Простые условия
Конструкция if позволяет выполнять в программе различные действия в зависимости от условий.
if (password == 12345) { //если значение переменной password равняется 12345, printf("Welcome!"); //вывести Welcome! } else { //в противном случае printf("Access denied!"); //вывести Access denied! }
Если ветка else не используется, её можно не писать:
if (lives <= 0) { //если количество жизней меньше или равно нулю, printf("Game over!"); //вывести Game over! } //иначе ничего не делать
Можно скомбинировать несколько условий при помощи else if:
if (mark == 5) { printf("Excellent!"); } else if (mark == 4) { printf("Good!"); } else if (mark == 3) { printf("Satisfactory"); } else { printf("Bad"); }
Операции сравнения
< | меньше |
<= | меньше или равно |
> | больше |
>= | больше или равно |
== | равно (не путать с =) |
!= | не равно |
Условия со связками И, ИЛИ
Связка И (&&) позволяет проверить, что обе части условия одновременно являются истинными:
if (20 <= age && age <= 30) //если возраст от 20 до 30 лет включительно
Связка ИЛИ (||) позволяет проверить, что хотя бы одна из частей условия является истинной:
if (age < 20 || 30 < age) //если возраст меньше 20 или больше 30 лет
Поиск максимума или минимума
Чтобы найти наибольшее из значений нескольких переменных, следует сделать следующие шаги:
- Создать новую переменную, в которой в итоге будет находиться значение максимума, и положить туда значение первой переменной;
- Сравнить максимум со второй переменной, и если вторая переменная больше, положить в максимум значение второй переменной;
- Сравнить максимум с третьей переменной, и если третья переменная больше, положить в максимум значение третьей переменной;
- Повторить для оставшихся переменных.
int maxValue = a; if (b > maxValue) { maxValue = b; } if (c > maxValue) { maxValue = c; } if (d > maxValue) { maxValue = d; }
Минимум определяется аналогичным образом (знаки > следует изменить на <).
Циклы
Цикл while
Циклы — это конструкции языка C++, позволяющие несколько раз выполнять однотипные действия.
Общий вид цикла while:
while (<условие>) {
<действия>
}
Перед началом цикла будет выполнена проверка, является ли <условие> истинным. Если это так, то выполняются действия, указанные внутри цикла (пока всё очень похоже на if). Однако, в отличие от if, при достижении закрывающей скобки цикла while мы перемещаемся обратно на его начало, где вновь будет проверено <условие>, и если оно всё ещё истинно, то снова выполняются действия внутри цикла, и так далее. Это продолжается до тех пор, пока <условие> не перестанет быть истинным (или пока не встретится оператор break; см. далее).
Цикл while удобно использовать тогда, когда заранее неизвестно, сколько именно повторов требуется сделать.
Примеры:
//В банке лежит n рублей, каждый месяц сумма увеличивается на 10%. //Сколько месяцев потребуется, чтобы скопить миллион рублей? int money = n, months = 0; //изначально денег в банке - n, прошло месяцев - 0 while (money < 1000000) { //пока не накопится миллион или больше, money *= 1.1; //сумма увеличивается на 10% (дробная часть отбрасывается) months++; //количество месяцев увеличивается на 1 } //цикл закончится в тот момент, когда money будет больше или равно миллиону printf("%d", months); //выводим количество прошедших месяцев
//поиск минимального делителя (большего единицы) числа n int divisor = 2; //считаем, что минимальный делитель — это двойка while (n % divisor != 0) { //пока n не делится на divisor, n++; //увеличиваем divisor } //цикл закончится в тот момент, когда n будет делиться на divisor printf("%d", divisor); //выводим полученный делитель
Цикл for
Цикл for удобно использовать тогда, когда количество повторений известно заранее.
Пусть, например, нужно вывести числа от 0 до 9. Это можно сделать при помощи цикла while:
int i = 0; while (i < 10) { printf("%d ", i); i++; }
Однако гораздо проще в данном случае использовать цикл for:
for (int i = 0; i < 10; i++) { printf("%d ", i); }
Запись цикла for всегда состоит из трёх частей, разделённых точками с запятой (именно точками с запятой, это важно!):
for (<инициализация>; <условие>; <изменение>) { <действия> }
- Как правило, внутри цикла for используется некоторая переменная (счётчик). Первая часть отвечает за создание счётчика и запись в него начального значения;
- Вторая часть содержит условие, при истинности которого цикл продолжает работу (оно имеет точно такой же смысл, как условие в скобках у while). Как правило, здесь проверяется, что счётчик ещё не дошёл до некоторого финального значения;
- Третья часть показывает, как должен изменяться счётчик от итерации к итерации.
Примеры:
for (int i = 5; i <= 15; i++) { printf("%d ", i); //Вывод: 5 6 7 8 9 10 11 12 13 14 15 }
for (int i = 30; i >= 20; i--) { printf("%d ", i); //Вывод: 30 29 28 27 26 25 24 23 22 21 20 }
for (int i = 0; i <= 40; i += 5) { printf("%d ", i); //Вывод: 0 5 10 15 20 25 30 35 40 }
for (int i = 1; i < 100; i *= 3) { printf("%d ", i); //Вывод: 1 3 9 27 81 243 729 }
Операторы break и continue
Оператор break досрочно завершает цикл while или for (если при выполнении программы мы встречаем break, мы сразу же перемещаемся за конец цикла):
for (int i = 0; i < 10; i++) { //цикл от 0 до 9 if (i % 4 == 0) { //если счётчик делится на 4, break; //прервать цикл } printf("%d ", i); //вывести счётчик } //Вывод: 0 1 2 3
Оператор continue досрочно переходит к следующей итерации цикла while или for (если при выполнении программы мы встречаем continue, мы сразу же перемещаемся к началу цикла; если есть счётчик, то он будет изменён):
for (int i = 0; i < 10; i++) { //цикл от 0 до 9 if (i % 4 == 0) { //если счётчик делится на 4, continue; //перейти к следующей итерации } printf("%d ", i); //вывести счётчик } //Вывод: 0 1 2 3 5 6 7 9
Массивы
Объявление и использование массивов
Массив — несколько переменных одного типа, имеющих общее имя и различные индексы. Для обращения к ячейке массива требуется написать имя массива, а затем — индекс ячейки в квадратных скобках.
int x; //одна переменная типа int, 4 байта int a[5]; //массив из 5 ячеек типа int, 20 байт
Ячейки массива имеют индексы от 0 до (SIZE - 1), где SIZE — размер массива.
int a[10]; //объявлены 10 ячеек: a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9] int b[100]; //объявлены 100 ячеек: от a[0] до a[99]
С ячейками массива можно работать как с обычными переменными:
int a[5]; a[0] = 100; a[1] = a[0] * 2; printf("%d", a[1]); //вывод: 200
При создании массива можно сразу задать ячейкам начальные значения (как и в случае с отдельными переменными). Если этого не сделать, массив изначально будет содержать случайные значения (мусор).
int x; //x — отдельная переменная, содержит случайное значение (мусор) int y = 100; //y — отдельная переменная, содержит значение 100 int a[3]; //a — массив из 3 ячеек, которые содержат случайные значения (мусор) int b[3] = {100, 200, 300}; //b — массив из 3 ячеек, которые содержат значения 100, 200 и 300
Считывание и вывод массивов
Если определён массив из 5 ячеек, и значения ячеек вводятся с клавиатуры, можно использовать 5 операций scanf:
int a[5]; scanf("%d", &a[0]); scanf("%d", &a[1]); scanf("%d", &a[2]); scanf("%d", &a[3]); scanf("%d", &a[4]);
Но проще и правильнее в данном случае использовать цикл for:
int a[5]; for (int i = 0; i < 5; i++) { scanf("%d", &a[i]); }
Часто в задачах размер массива неизвестен заранее, и его также нужно вводить с клавиатуры. В этом случае нужно объявить массив на такое количество ячеек, которого заведомо хватит во всех случаях (как правило, узнать это количество можно из ограничений в разделе «Входные данные»), а затем сделать отдельную переменную size и использовать её.
int size; //объявляем переменную для фактического размера массива scanf("%d", &size); //считываем размер массива int a[100010]; //объявляем массив такой величины, чтобы его хватило для всех тестов for (int i = 0; i < size; i++) { //считываем столько ячеек массива, сколько указано в size scanf("%d", &a[i]); }
Аналогичным образом выполняется вывод ячеек массива на печать:
for (int i = 0; i < size; i++) { printf("%d ", a[i]); }