Основы программирования на C++: различия между версиями
Ctrlalt (обсуждение | вклад) |
Spiritum (обсуждение | вклад) Нет описания правки |
||
(не показано 18 промежуточных версий 2 участников) | |||
Строка 1: | Строка 1: | ||
== Подготовка к работе == | == Подготовка к работе == | ||
Строка 12: | Строка 5: | ||
: Выберите только вариант «Разработка классических приложений на C++» | : Выберите только вариант «Разработка классических приложений на C++» | ||
* [http://download.microsoft.com/download/1/D/9/1D9A6C0E-FC89-43EE-9658-B9F0E3A76983/vc_web.exe Visual Studio 2010] (для Windows XP, но также '''<span style='color:red;'>рекомендуется, если вы не хотите выкачивать большие установочные файлы</span>''') | * [http://download.microsoft.com/download/1/D/9/1D9A6C0E-FC89-43EE-9658-B9F0E3A76983/vc_web.exe Visual Studio 2010] (для Windows XP, но также '''<span style='color:red;'>рекомендуется, если вы не хотите выкачивать большие установочные файлы</span>''') | ||
=== Создание проекта в Visual Studio === | === Создание проекта в Visual Studio === | ||
Строка 36: | Строка 28: | ||
== Вспомогательные материалы к занятиям == | == Вспомогательные материалы к занятиям == | ||
=== Введение. Переменные. Ввод-вывод === | === Введение. Переменные. Ввод-вывод === | ||
Минимальная программа на C++ | ==== Минимальная программа на C++ ==== | ||
int main() { | int main() { | ||
} | } | ||
Использование переменных: | В любой программе всегда должна быть функция main. Фигурные скобки обозначают начало и конец функции, все команды записываются внутри. | ||
До функции main, в самом начале файла, обычно указываются директивы #include (например #include <stdio.h>). | |||
==== Использование переменных ==== | |||
Чтобы добавить в программу переменную, укажите её тип, название и, если необходимо, начальное значение. | |||
int radius = 100; //целое число radius со значением 100 | |||
double circleArea = 3.14 * radius * radius; //дробное число circleArea, значение вычисляется по формуле | |||
Переменные могут менять своё значение: | |||
radius = radius * 2; //радиус увеличился в 2 раза | |||
Часто используемые типы данных: | |||
{| border=black; cellspacing=0; cellpadding=5px; | |||
| int || целые числа || от -2<sup>31</sup> до 2<sup>31</sup>-1 (примерно от -2·10<sup>9</sup> до 2·10<sup>9</sup>) || 4 байта | |||
|- | |||
| long long || большие целые числа || от -2<sup>63</sup> до 2<sup>63</sup>-1 (примерно от -9·10<sup>18</sup> до 9·10<sup>18</sup>) || 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 $. | |||
Часто используемые спецификаторы: | |||
{| border=black; cellspacing=0; cellpadding=5px; | |||
| %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"); | |||
} | |||
==== Операции сравнения ==== | |||
{| border=black; cellspacing=0; cellpadding=5px; | |||
| <tt><</tt> || меньше | |||
|- | |||
| <tt><=</tt> || меньше или равно | |||
|- | |||
| <tt>></tt> || больше | |||
|- | |||
| <tt>>=</tt> || больше или равно | |||
|- | |||
| <tt>==</tt> || равно (не путать с <tt>=</tt>) | |||
|- | |||
| <tt>!=</tt> || не равно | |||
|} | |||
==== Условия со связками И, ИЛИ ==== | |||
Связка И (&&) позволяет проверить, что '''обе''' части условия '''одновременно''' являются истинными: | |||
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 (<span style='color:orange'><условие></span>) { | |||
<действия> | |||
} | |||
Перед началом цикла будет выполнена проверка, является ли <span style='color:orange'><условие></span> истинным. Если это так, то выполняются действия, указанные внутри цикла (пока всё очень похоже на if). Однако, в отличие от if, при достижении закрывающей скобки цикла while мы перемещаемся обратно на его начало, где вновь будет проверено <span style='color:orange'><условие></span>, и если оно всё ещё истинно, то снова выполняются действия внутри цикла, и так далее. Это продолжается до тех пор, пока <span style='color:orange'><условие></span> не перестанет быть истинным (или пока не встретится оператор 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 (<span style='color:red'><инициализация></span>; <span style='color:orange'><условие></span>; <span style='color:green'><изменение></span>) { | |||
<действия> | |||
} | |||
* Как правило, внутри цикла for используется некоторая переменная (счётчик). <span style='color:red'>Первая часть</span> отвечает за создание счётчика и запись в него начального значения; | |||
* <span style='color:orange'>Вторая часть</span> содержит условие, при истинности которого цикл продолжает работу (оно имеет точно такой же смысл, как условие в скобках у while). Как правило, здесь проверяется, что счётчик ещё не дошёл до некоторого финального значения; | |||
* <span style='color:green'>Третья часть</span> показывает, как должен изменяться счётчик от итерации к итерации. | |||
Примеры: | |||
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]); | |||
} | |||
<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]); | |||
} | |||
=== Символы и строки === | |||
==== Символы в языке С ==== | |||
Язык С использует [http://ru.wikipedia.org/wiki/ASCII кодировочную таблицу ASCII], в которой различным знакам сопоставлены коды от 0 до 127. В языке C '''отсутствует отдельный тип для хранения символов''', а '''маленькие целые числа (от 0 до 127) всегда могут интерпретироваться как символы и наоборот'''. | |||
Для хранения кодов удобно использовать 8-битный целый тип char (может представлять целые числа от -128 до 127, чего как раз хватает для кодов символов). | |||
char a = 33; //a - это число 33, или, что то же самое, код символа '!' | |||
printf("%d\n", a); //вывод: 33 | |||
printf("%c\n", a); //вывод: ! | |||
char b = '@'; //b - это код символа '@', или, что то же самое, число 64 | |||
printf("%d\n", b); //вывод: 64 | |||
printf("%c\n", b); //вывод: @ | |||
==== Запись, ввод и вывод символов ==== | |||
Если в программе нужно использовать символьную константу, она заключается в '''одинарные''' кавычки. | |||
char x = '$'; //в переменную x записывается код знака доллара - 36 | |||
Для ввода одного символа используют scanf() со спецификатором %с. | |||
<span style="color: red">Важно: спецификаторы %d и %lf при вводе игнорируют пробелы, переводы строки и т. п. Если в программе записано scanf("%d%d", &a, &b), и вводится «12 34», то a и b будут считаны правильно (a == 12, b == 34).</span> | |||
<span style="color: red">Однако %c может считывать пробелы и переводы строк. Если в программе записано scanf("%c%c", &a, &b), и вводится «X Y», то в b будет записан пробел (a == 'X', b == ' ').</span> | |||
<span style="color: red">Если этого нужно избежать, перед %c нужно ставить пробел. Это указание для scanf: пропустить все пробельные символы (если они есть) и прочитать первый непробельный.</span> | |||
char x; | |||
scanf(" %c", &x); | |||
Для вывода одного символа используется printf() со спецификатором %c. Если нужно вывести не символ, а его код, следует использовать спецификатор %d. | |||
char x = '?' | |||
printf("Code of %c is %d"); //выведет Code of ? is 63 | |||
==== Распространённые действия с символами ==== | |||
Чтобы проверить, является ли символ цифрой, можно использовать тот факт, что коды символов от '0' до '9' в таблице ASCII расположены последовательно. Следовательно, если символ — цифра, то его код должен находиться между '0' и '9'. | |||
if ('0' <= x && x <= '9') //проверка, является ли x цифрой | |||
Аналогично производятся проверки, является ли символ строчной (заглавной) латинской буквой. | |||
if ('a' <= x && x <= 'z') //проверка, является ли x строчной буквой | |||
if ('A' <= x && x <= 'Z') //проверка, является ли x заглавной буквой | |||
Чтобы сделать из строчной буквы заглавную, нужно добавить к коду строчной буквы смещение до блока заглавных букв (то есть дистанцию от символа 'a' до символа 'A') | |||
x += ('A' - 'a'); //преобразование строчной буквы в заглавную (x должен быть строчной буквой!) | |||
x += ('a' - 'A'); //преобразование заглавной буквы в строчную (x должен быть заглавной буквой!) | |||
Работу с символами облегчает библиотека <ctype.h>, которая содержит множество удобных функций: | |||
* isdigit(x) — проверка, является ли x цифрой ( <tt>if (isdigit(x))</tt> ) | |||
* islower(x) — проверка, является ли x строчной буквой | |||
* isupper(x) — проверка, является ли x заглавной буквой | |||
* isalpha(x) — проверка, является ли x буквой | |||
* tolower(x) — возвращает строчную букву, соответствующую x ( <tt>x = tolower(x);</tt> ) | |||
* toupper(x) — возвращает заглавную букву, соответствующую x | |||
==== Строки в языке C ==== | |||
Строки — это массивы символов. | |||
char name[6] = "Vasya"; | |||
Для обозначения конца строки используется специальный символ — завершающий ноль ('\n', ASCII-код 0). Поэтому '''для хранения строки из N символов требуется массив из не менее чем (N + 1) ячеек''' (например, для строки "Vasya" нужно не менее 6 ячеек). | |||
Если завершающий ноль будет утерян, строку не получится обработать стандартными функциями (например, print). | |||
==== Запись, ввод и вывод строк ==== | |||
Строковые константы записываются в '''двойных''' кавычках. | |||
char city[20] = "Ulyanovsk"; | |||
Для ввода строки '''до пробела''' используется scanf() со спецификатором %s. | |||
char name[100]; | |||
scanf("%s", &name); //при вводе "Vasily Pupkin" в name будет записано "Vasily" | |||
Для ввода строки '''целиком (до перевода строки)''' используется scanf() со спецификатором %[^\n]. | |||
char name[100]; | |||
scanf("%[^\n]", &name); //при вводе "Vasily Pupkin" в name будет записано "Vasily Pupkin" | |||
Для вывода строк используется printf() со спецификатором %s. | |||
char city[20] = "Ulyanovsk"; | |||
printf("Welcome to %s", city); //выведет Welcome to Ulyanovsk | |||
==== Распространённые действия со строками ==== | |||
Для обхода всех символов строки используется цикл for, продолжающийся до тех пор, пока текущим символом не окажется завершающий ноль. | |||
char s[20] = "Ulyanovsk"; | |||
for (int i = 0; s[i] != 0; i++) { | |||
printf("%c ", s[i]); //выведет U l y a n o v s k | |||
} | |||
Полезные функции для работы со строками содержатся в заголовочном файле [http://www.cplusplus.com/reference/cstring/ <string.h>]. Наиболее часто используемые из них: | |||
* strlen(s) — возвращает длину строки s (без учёта завершающего нуля); | |||
* strcpy(s1, s2) — копирует строку s2 в s1 (аналог несуществующей операции s1 = s2); | |||
* strcat(s1, s2) — дописывает строку s2 к s1 (аналог несуществующей операции s1 += s2); | |||
* strcmp(s1, s2) — возвращает 0, если строки s1 и s2 равны, отрицательное число, если s1 лексикографически меньше s2, либо положительное число, если s2 лексикографически больше s2 (аналог несуществующих операций s1 == s2, s1 < s2, s1 > s2); | |||
* strchr(s, x) — возвращает указатель на первое вхождение символа x в строку s либо 0, если x не содержится в s. Чтобы получить индекс символа x в строке s, нужно записать <tt>int index = strchr(s, x) - s;</tt> | |||
* strstr(s1, s2) — возвращает указатель на первое вхождение строки s2 в строку s1 либо 0, если s2 не содержится в s1. Чтобы получить индекс строки s2 в строке s1, нужно записать <tt>int index = strstr(s1, s2x) - s1;</tt> | |||
==== Строки в стиле C++ ==== | |||
В языке C++ для хранения строк используется специальный тип string. Чтобы получить к нему доступ, нужно подключить заголовочный файл [http://www.cplusplus.com/reference/string/ <string>] (не путать со <string.h>!) и пространство имён std. | |||
#include <string> | |||
using namespace std; | |||
int main() { | int main() { | ||
string s = "Hello!"; | |||
} | } | ||
Строки типа string нельзя вводить при помощи scanf. Для ввода следует использовать одну из двух возможностей: | |||
{| | |||
| width="50%" | | |||
#include <stdio.h> | #include <stdio.h> | ||
#include <string> | |||
using namespace std; | |||
int main() { | |||
char buffer[100]; | |||
scanf(" %s", &buffer); | |||
string s = buffer; | |||
} | |||
| width="10px" | | |||
| width="50%" | | |||
#include <iostream> | |||
#include <string> | |||
using namespace std; | |||
int main() { | int main() { | ||
printf("Hello | string s; | ||
cin >> s; | |||
} | |||
|} | |||
Для вывода строки типа string с помощью printf необходимо предварительно вызвать у строки метод .c_str(), возвращающий аналог строки в старом стиле. | |||
string s = "Hello"; | |||
printf("%s", s.c_str()); | |||
Возможности строк типа string: | |||
* Индексация отдельных символов через квадратные скобки, как у массивов; | |||
* Получение размера строки вызовом метода .size(); | |||
* Присваивание строк оператором =; | |||
* Конкатенация строк операторами + и +=; | |||
* Сравнение строк операторами ==, !=, <, >; | |||
* Поиск символов и подстрок в строке вызовом метода .find() (возвращает индекс вхождения либо -1, если вхождение не найдено); | |||
* Получение подстрок вызовом метода .substr(). | |||
=== Функции === | |||
==== Определение функций ==== | |||
Определение функции в языке C++ имеет следующий вид (количество параметров может быть иным): | |||
типВозвращаемогоЗначения имяФункции(типПараметра1 имяПараметра1, типПараметра2 имяПараметра2) { | |||
} | |||
Для возврата значения из функции используется ключевое слово return. При достижении строки с return функция немедленно завершается, а в место её вызова подставляется значение, записанное справа от return. | |||
double | |||
printf("%. | Пример: функции, вычисляющие площадь различных геометрических фигур: | ||
double rectangleArea(double width, double height) { | |||
return width * height; | |||
} | |||
double triangleArea(double a, double b, double c) { | |||
double p = (a + b + c) / 2; | |||
return sqrt(p * (p - a) * (p - b) * (p - c)); | |||
} | |||
double circleArea(double radius) { | |||
double pi = acos(-1.0); | |||
return pi * radius * radius; | |||
} | |||
Вызвать функцию может любая другая функция, расположенная ниже: | |||
double segmentLength(double ax, double ay, double dx, double by) { | |||
double dx = ax - bx; | |||
double dy = ay - by; | |||
return sqrt(dx * dx + dy * dy); | |||
} | |||
double triangleArea(double ax, double ay, double dx, double by, double cx, double cy) { | |||
double ab = segmentLength(ax, ay, bx, by); | |||
double ac = segmentLength(ax, ay, cx, cy); | |||
double bc = segmentLength(bx, by, cx, cy); | |||
double p = (ab + ac + bc) / 2; | |||
return sqrt(p * (p - ab) * (p - ac) * (p - bc)); | |||
} | |||
int main() { | |||
printf("%lf", triangleArea(0, 0, 10, 0, 0, 10)); | |||
} | |||
Функция может не иметь возвращаемого значения. Для обозначения такой функции используется ключевое слово void. | |||
//функция, n раз выводящая символ c | |||
void repeatSymbol(char c, int n) { | |||
for (int i = 0; i < n; i++) | |||
printf("%c", c); | |||
} | |||
==== Передача параметров в функцию ==== | |||
По умолчанию используется передача параметров по значению. Её особенности: | |||
* Внутри функции создаются '''копии''' переданных переменных; | |||
* Изменения, произошедшие с параметрами внутри функции, '''не сохранятся''' вне функции. | |||
void swap(int a, int b) { | |||
int t = a; | |||
a = b; | |||
b = t; | |||
} | |||
int main() { | |||
int x = 10, y = 20; | |||
swap(x, y); | |||
printf("x=%d y=%d"); //будет выведено x=10 y=20 | |||
} | |||
Старый способ сохранения сделанных внутри функции изменений — передача по указателю (вместо самих переменных передаются их адреса, см. функцию scanf). | |||
Современный способ сохранения сделанных внутри функции изменений — передача по ссылке. | |||
Добавление знака & перед именем параметра означает передачу по ссылке. Её особенности: | |||
* Внутри функции используются '''непосредственно сами''' переданные переменные; | |||
* Изменения, произошедшие с параметрами внутри функции, '''сохранятся''' вне функции; | |||
* По ссылке невозможно передать константы. | |||
void swap(int &a, int &b) { | |||
int t = a; | |||
a = b; | |||
b = t; | |||
} | |||
int main() { | int main() { | ||
int x = 10, y = 20; | |||
swap(x, y); | |||
printf("x=%d y=%d"); //будет выведено x=20 y=10 | |||
} | |||
Массивы всегда передаются по ссылке. При передаче массива в функцию он теряет возможность узнать свой размер, поэтому часто вместе с массивом передаётся количество элементов в нём. | |||
int sum(int a[], int size) { | |||
int res = 0; | |||
for (int i = 0; i < size; i++) | |||
res += a[i]; | |||
return res; | |||
} |
Текущая версия от 17:00, 1 мая 2019
Подготовка к работе
Установка среды разработки
- 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]); }
Символы и строки
Символы в языке С
Язык С использует кодировочную таблицу ASCII, в которой различным знакам сопоставлены коды от 0 до 127. В языке C отсутствует отдельный тип для хранения символов, а маленькие целые числа (от 0 до 127) всегда могут интерпретироваться как символы и наоборот.
Для хранения кодов удобно использовать 8-битный целый тип char (может представлять целые числа от -128 до 127, чего как раз хватает для кодов символов).
char a = 33; //a - это число 33, или, что то же самое, код символа '!' printf("%d\n", a); //вывод: 33 printf("%c\n", a); //вывод: ! char b = '@'; //b - это код символа '@', или, что то же самое, число 64 printf("%d\n", b); //вывод: 64 printf("%c\n", b); //вывод: @
Запись, ввод и вывод символов
Если в программе нужно использовать символьную константу, она заключается в одинарные кавычки.
char x = '$'; //в переменную x записывается код знака доллара - 36
Для ввода одного символа используют scanf() со спецификатором %с.
Важно: спецификаторы %d и %lf при вводе игнорируют пробелы, переводы строки и т. п. Если в программе записано scanf("%d%d", &a, &b), и вводится «12 34», то a и b будут считаны правильно (a == 12, b == 34).
Однако %c может считывать пробелы и переводы строк. Если в программе записано scanf("%c%c", &a, &b), и вводится «X Y», то в b будет записан пробел (a == 'X', b == ' ').
Если этого нужно избежать, перед %c нужно ставить пробел. Это указание для scanf: пропустить все пробельные символы (если они есть) и прочитать первый непробельный.
char x; scanf(" %c", &x);
Для вывода одного символа используется printf() со спецификатором %c. Если нужно вывести не символ, а его код, следует использовать спецификатор %d.
char x = '?' printf("Code of %c is %d"); //выведет Code of ? is 63
Распространённые действия с символами
Чтобы проверить, является ли символ цифрой, можно использовать тот факт, что коды символов от '0' до '9' в таблице ASCII расположены последовательно. Следовательно, если символ — цифра, то его код должен находиться между '0' и '9'.
if ('0' <= x && x <= '9') //проверка, является ли x цифрой
Аналогично производятся проверки, является ли символ строчной (заглавной) латинской буквой.
if ('a' <= x && x <= 'z') //проверка, является ли x строчной буквой
if ('A' <= x && x <= 'Z') //проверка, является ли x заглавной буквой
Чтобы сделать из строчной буквы заглавную, нужно добавить к коду строчной буквы смещение до блока заглавных букв (то есть дистанцию от символа 'a' до символа 'A')
x += ('A' - 'a'); //преобразование строчной буквы в заглавную (x должен быть строчной буквой!)
x += ('a' - 'A'); //преобразование заглавной буквы в строчную (x должен быть заглавной буквой!)
Работу с символами облегчает библиотека <ctype.h>, которая содержит множество удобных функций:
- isdigit(x) — проверка, является ли x цифрой ( if (isdigit(x)) )
- islower(x) — проверка, является ли x строчной буквой
- isupper(x) — проверка, является ли x заглавной буквой
- isalpha(x) — проверка, является ли x буквой
- tolower(x) — возвращает строчную букву, соответствующую x ( x = tolower(x); )
- toupper(x) — возвращает заглавную букву, соответствующую x
Строки в языке C
Строки — это массивы символов.
char name[6] = "Vasya";
Для обозначения конца строки используется специальный символ — завершающий ноль ('\n', ASCII-код 0). Поэтому для хранения строки из N символов требуется массив из не менее чем (N + 1) ячеек (например, для строки "Vasya" нужно не менее 6 ячеек).
Если завершающий ноль будет утерян, строку не получится обработать стандартными функциями (например, print).
Запись, ввод и вывод строк
Строковые константы записываются в двойных кавычках.
char city[20] = "Ulyanovsk";
Для ввода строки до пробела используется scanf() со спецификатором %s.
char name[100]; scanf("%s", &name); //при вводе "Vasily Pupkin" в name будет записано "Vasily"
Для ввода строки целиком (до перевода строки) используется scanf() со спецификатором %[^\n].
char name[100]; scanf("%[^\n]", &name); //при вводе "Vasily Pupkin" в name будет записано "Vasily Pupkin"
Для вывода строк используется printf() со спецификатором %s.
char city[20] = "Ulyanovsk"; printf("Welcome to %s", city); //выведет Welcome to Ulyanovsk
Распространённые действия со строками
Для обхода всех символов строки используется цикл for, продолжающийся до тех пор, пока текущим символом не окажется завершающий ноль.
char s[20] = "Ulyanovsk"; for (int i = 0; s[i] != 0; i++) { printf("%c ", s[i]); //выведет U l y a n o v s k }
Полезные функции для работы со строками содержатся в заголовочном файле <string.h>. Наиболее часто используемые из них:
- strlen(s) — возвращает длину строки s (без учёта завершающего нуля);
- strcpy(s1, s2) — копирует строку s2 в s1 (аналог несуществующей операции s1 = s2);
- strcat(s1, s2) — дописывает строку s2 к s1 (аналог несуществующей операции s1 += s2);
- strcmp(s1, s2) — возвращает 0, если строки s1 и s2 равны, отрицательное число, если s1 лексикографически меньше s2, либо положительное число, если s2 лексикографически больше s2 (аналог несуществующих операций s1 == s2, s1 < s2, s1 > s2);
- strchr(s, x) — возвращает указатель на первое вхождение символа x в строку s либо 0, если x не содержится в s. Чтобы получить индекс символа x в строке s, нужно записать int index = strchr(s, x) - s;
- strstr(s1, s2) — возвращает указатель на первое вхождение строки s2 в строку s1 либо 0, если s2 не содержится в s1. Чтобы получить индекс строки s2 в строке s1, нужно записать int index = strstr(s1, s2x) - s1;
Строки в стиле C++
В языке C++ для хранения строк используется специальный тип string. Чтобы получить к нему доступ, нужно подключить заголовочный файл <string> (не путать со <string.h>!) и пространство имён std.
#include <string> using namespace std; int main() { string s = "Hello!"; }
Строки типа string нельзя вводить при помощи scanf. Для ввода следует использовать одну из двух возможностей:
#include <stdio.h> #include <string> using namespace std; int main() { char buffer[100]; scanf(" %s", &buffer); string s = buffer; } |
#include <iostream> #include <string> using namespace std; int main() { string s; cin >> s; } |
Для вывода строки типа string с помощью printf необходимо предварительно вызвать у строки метод .c_str(), возвращающий аналог строки в старом стиле.
string s = "Hello"; printf("%s", s.c_str());
Возможности строк типа string:
- Индексация отдельных символов через квадратные скобки, как у массивов;
- Получение размера строки вызовом метода .size();
- Присваивание строк оператором =;
- Конкатенация строк операторами + и +=;
- Сравнение строк операторами ==, !=, <, >;
- Поиск символов и подстрок в строке вызовом метода .find() (возвращает индекс вхождения либо -1, если вхождение не найдено);
- Получение подстрок вызовом метода .substr().
Функции
Определение функций
Определение функции в языке C++ имеет следующий вид (количество параметров может быть иным):
типВозвращаемогоЗначения имяФункции(типПараметра1 имяПараметра1, типПараметра2 имяПараметра2) { }
Для возврата значения из функции используется ключевое слово return. При достижении строки с return функция немедленно завершается, а в место её вызова подставляется значение, записанное справа от return.
Пример: функции, вычисляющие площадь различных геометрических фигур:
double rectangleArea(double width, double height) { return width * height; } double triangleArea(double a, double b, double c) { double p = (a + b + c) / 2; return sqrt(p * (p - a) * (p - b) * (p - c)); } double circleArea(double radius) { double pi = acos(-1.0); return pi * radius * radius; }
Вызвать функцию может любая другая функция, расположенная ниже:
double segmentLength(double ax, double ay, double dx, double by) { double dx = ax - bx; double dy = ay - by; return sqrt(dx * dx + dy * dy); } double triangleArea(double ax, double ay, double dx, double by, double cx, double cy) { double ab = segmentLength(ax, ay, bx, by); double ac = segmentLength(ax, ay, cx, cy); double bc = segmentLength(bx, by, cx, cy); double p = (ab + ac + bc) / 2; return sqrt(p * (p - ab) * (p - ac) * (p - bc)); } int main() { printf("%lf", triangleArea(0, 0, 10, 0, 0, 10)); }
Функция может не иметь возвращаемого значения. Для обозначения такой функции используется ключевое слово void.
//функция, n раз выводящая символ c void repeatSymbol(char c, int n) { for (int i = 0; i < n; i++) printf("%c", c); }
Передача параметров в функцию
По умолчанию используется передача параметров по значению. Её особенности:
- Внутри функции создаются копии переданных переменных;
- Изменения, произошедшие с параметрами внутри функции, не сохранятся вне функции.
void swap(int a, int b) { int t = a; a = b; b = t; } int main() { int x = 10, y = 20; swap(x, y); printf("x=%d y=%d"); //будет выведено x=10 y=20 }
Старый способ сохранения сделанных внутри функции изменений — передача по указателю (вместо самих переменных передаются их адреса, см. функцию scanf).
Современный способ сохранения сделанных внутри функции изменений — передача по ссылке.
Добавление знака & перед именем параметра означает передачу по ссылке. Её особенности:
- Внутри функции используются непосредственно сами переданные переменные;
- Изменения, произошедшие с параметрами внутри функции, сохранятся вне функции;
- По ссылке невозможно передать константы.
void swap(int &a, int &b) { int t = a; a = b; b = t; } int main() { int x = 10, y = 20; swap(x, y); printf("x=%d y=%d"); //будет выведено x=20 y=10 }
Массивы всегда передаются по ссылке. При передаче массива в функцию он теряет возможность узнать свой размер, поэтому часто вместе с массивом передаётся количество элементов в нём.
int sum(int a[], int size) { int res = 0; for (int i = 0; i < size; i++) res += a[i]; return res; }