Язык программирования, как и любой другой язык, обладает синтаксисом и нормами оформления (форматирования). Как и в обычном языке, например в русском или английском, ошибка в слове или пропущенная запятая будет являться ошибкой синтаксиса, а пропущенный пробел после знака препинания - ошибкой оформления, то есть написанное будет корректным, но "не таким, как все".
Синтаксис - набор строгих правил написания программы, ошибка в синтаксисе языка программирования приведёт к ошибке при компиляции или проверке программы, так как компьютер буквально не поймёт, чего от него хотят.
В большинстве IDE есть автоформатирование - автоматическое перестраивание кода программы под стандарт оформления - соблюдение пробелов, отступов и переносов строк в нужных местах. Таких стандартов для C/C++ несколько и они отличаются в некоторых моментах. В некоторых IDE можно тонко настроить автоформатирование под себя.
Код программы состоит из нескольких сущностей:
- Комментарий - текстовая заметка для пояснения программы
- Переменная - именованная ячейка для хранения данных
- Функция - код, который можно вызвать по его имени. По сути - переменная для хранения другого кода
- Объект - составная переменная, состоящая из других переменных и функций
- Оператор - операции взаимодействия между переменными и функциями
- Директива препроцессора - команда компилятору (препроцессору) на выполнение различных действий
- А также набор атрибутов, модификаторов и некоторых других специальных слов
В этом уроке рассмотрен базовый синтаксис. Более подробно отдельные части будут разобраны в следующих уроках
Комментарии #
В коде можно оставлять текстовые заметки для пояснения программы или скрытия её частей - комментарии игнорируются компилятором и нужны только для удобства программиста. Есть два типа комментариев:
- Однострочный - начинается с
//
и покрывает всю строку до конца - Многострочный - начинается с
/*
и покрывает весь текст до закрывающего*/
// однострочный комментарий
// ещё один
/*
многострочный
комментарий
// однострочный внутри многострочного, не будет ошибкой
*/
/* многострочный в одной строке */
Ключевые слова #
В языке есть зарезервированные компилятором слова и символы, которые выполняют конкретные задачи и должны использоваться строго определённым образом. Например нельзя просто так взять и использовать слово for
в программе в своих целях, это оператор. Если в текстовом редакторе IDE есть подсветка синтаксиса, то зарезервированные слова всегда выделяются отдельным цветом, как и на этом сайте. Например:
table
while // занято
void // занято
cat
dog
static // занято
Пользовательские имена #
Программист может создавать свои сущности (переменные, функции, типы данных) и давать им имена для удобства чтения и написания кода. На имя действуют следующие ограничения:
- Может состоять только из латинских букв (больших и маленьких), цифр и знака подчёркивания
- Не может начинаться с цифры
- Не может совпадать с ключевым словом
C/C++ чувствителен к регистру букв, то есть name
и Name
- это разные имена
abcd // корректно
ab cd // некорректно, это два имени
a // корректно
1a // некорректно, начинается с цифры
void // некорректно, системное слово
_a // корректно
Имена приватных (системных, непубличных) сущностей принято начинать с подчёркивания, например _buffer
. В то же время не стоит начинать имена с двойного подчёркивания - __buffer
- в системных библиотеках могут уже существовать сущности с таким именем (а их там довольно много) и пересечение с ними может привести к ошибке или непредсказуемой работе программы.
Стиль #
Есть несколько общепринятых стилей написания пользовательских имён:
- змеиный_стиль - строчные буквы, разделитель слов - подчёркивание:
snake_case
,my_var
. Принято использовать для имён переменных и функций - КРИЧАЩАЯ_ЗМЕЯ - прописные буквы, разделитель слов - подчёркивание:
SCREAMING_SNAKE
,MY_VAR
. Принято использовать для констант - верблюжийСтиль - слова не разделяются, первая буква каждого следующего слова, кроме первого - прописная:
camelCase
,myVar
. Принято использовать для имён переменных и функций - СтильПаскаля - слова не разделяются, первая буква каждого следующего слова - прописная:
PascalStyle
,MyVar
. Принято использовать для имён типов данных и классов
Названия #
Имя должно отражать суть того, что за ним находится, это делает код читаемым и самодокументированным - программа с хорошо подобранными именами практически не нуждается в пояснениях и комментариях.
Количество букв в именах никаким образом не влияет на вес скомпилированной программы и скорость её выполнения - это всё нужно для удобства программиста: после компиляции все имена превращаются в адреса в памяти
Для визуальной экономии места иногда сокращают имена, но нужно знать меру. Плохо читаемые, сильно сокращённые или ничего не означающие имена являются плохой практикой в любом языке:
temperature = readSensor();
a = b(); // что здесь происходит?
Имена переменных чаще всего описываются существительными, тогда как имена функций рекомендуется начинать с глагола, отражающего действие, которая эта функция выполняет. Например readSensor()
вместо sensorRead()
или setValue()
вместо valueSet()
.
Да, для написания и чтения программы нужно знать английский хотя бы на базовом уровне. Часто используемых слов на самом деле не так уж и много:
button
,btn
- кнопкаindex
,idx
,i
- индексbuffer
,buf
- буферtemp
,t
- временное значениеvalue
,val
- значениеvariable
,var
- переменнаяpointer
,ptr
- указательget
- получитьset
- установитьprint
,show
- вывести, показатьread
- прочитатьwrite
- записатьchange
- изменитьupdate
- обновитьclear
- очиститьbegin
,start
- начать, запуститьend
,stop
- закончить, остановитьfoo
,bar
- абстрактные слова-заглушки для использования в примерах, аналог "Ивана Петрова" и "John Doe" в документах
В поясняющих примерах к данным урокам будут часто использоваться абстрактные имена foo
и bar
- привыкайте, в другой литературе они тоже встречаются повсеместно
Отступы и переносы #
Пробелы и переносы строк в коде программы игнорируются компилятором и нужны только для повышения читаемости кода. Как и в обычном языке, пробелы ставятся после знаков препинания и вообще слов в целом:
// неформатированный код
for(int i=0;i<5;i++){foo();}
// форматированный код
for (int i = 0; i < 5; i++) {
foo();
}
В некоторых случаях компилятор может выдать предупреждение (не ошибку), мол, "ты понимаешь, что вот тут написано и как оно будет работать?" Пример:
if (a) foo(); bar();
// здесь компилятор предупредит, что по условию выполнится только foo()
Инструкции #
Одно законченное действие является инструкцией, она может быть как простой, так и составной. Инструкция должна заканчиваться точкой с запятой - ;
, пропущенная точка с запятой приведёт к ошибке компиляции. В то же время лишние точки с запятой будут проигнорированы компилятором и не являются ошибкой:
a = 10;
b = 20;; // не ошибка
;;; // не ошибка
c = 30 // ошибка
foo() // ошибка
bar();
Принято писать по одной инструкции в строке, как выше. Написание нескольких инструкций в одну строку не является ошибкой, но может снизить читаемость кода и является плохой практикой. Автоформатирование в большинстве случаев разделит такой код на несколько строк:
a = 10; b = 20; // фу!
Инструкция, состоящая просто из числа или имени переменной не несёт смысла, но и не является ошибкой - компилятор просто вырежет её:
a;
123;
Запятая #
Оператор запятая ,
позволяет объединять несколько инструкций в одну строку, выполнение кода идёт слева направо:
a = 10, b = 20;
Всё выражение, разделённое запятыми, в результате выполнения получает значение самой правой инструкции:
// логические скобки, чтобы отделить инструкции
a = (1, 2, 3);
// здесь a равно 3
Перенос строки #
Практически в любом месте программы можно перенести часть строки кода на другую строку, это может пригодиться при составлении длинных арифметических или логических выражений. В этом случае принято выравнивать код по последнему оператору в первой строке:
a = b + c * 10 - d * (b - 15) + c / 20 - e;
a = b + c * 10 -
d * (b - 15) +
c / 20 - e;
Блоки кода #
Блоки кода в C/C++ обрамляются фигурными скобками {}
. Точки с запятой и фигурные скобки - отличительные черты языка, языки с таким синтаксисом называются Си-подобными (Java, JS, Rust). Заключение кода в фигурные скобки позволяет чётко разделить его на блоки.
Такое разделение будет корректно работать при любом форматировании и даже полном отсутствии пробелов и переносов строк
При открытии блока кода принято делать горизонтальный отступ от его границы, это позволяет визуально разделить код и улучшить его читаемость. Отступом могут быть два пробела, четыре пробела или табуляция (клавиша Tab) - некоторые IDE заменяют табуляцию на указанное в настройках количество пробелов:
{
a = b;
}
Блоки кода могут существовать сами по себе и вкладываться друг в друга, это может использоваться в некоторых хитрых конструкциях и свойствах языка, о которых мы поговорим в следующих уроках:
// code
{
// code
{
// code
}
// code
}
Блок кода может открываться после некоторых операторов, условий и при создании функцй. Тут есть два стандарта: один предписывает переносить фигурную скобку на новую строку, а второй - нет. Мне больше нравится второй вариант:
// 1
if (a)
{
if (b)
{
// code
}
}
// 2
if (a) {
if (b) {
// code
}
}
Ещё один момент - перенос строки перед одной инструкцией, я опять же предпочитаю второй вариант:
// 1
if (condition)
foo();
// 2
if (condition) foo();
Функция #
Функция - блок кода, которому присвоено название (имя функции), по которому этот блок можно вызвать из другого места в программе при помощи конструкции имя_функции()
. Про функции подробно поговорим в отдельном уроке, сейчас достаточно знать основы:
// создание функции
void func() {
// тело функции
}
// главная функция программы
int main() {
func(); // вызов нашей функции
func();
}
Структура программы #
"Точкой входа" в программу на C/C++ является функция int main()
(о функциях подробно в другом уроке) - с этой функции программа начинает работу, эта функция обязательно должна быть в коде - без неё программа даже не скомпилируется:
int main() {
// выполнение начинается отсюда
}
Основные тезисы урока #
- Синтаксис - набор строгих правил языка, которые нельзя нарушать - программа не скомпилируется
- Форматирование - оформление кода, соблюдение отступов и переносов, которое делает программу более читаемой
- Автоформатирование - автоматическое перестраивание кода программы под стандарт оформления
- Однострочный комментарий -
// комментарий
- Многострочный комментарий -
/* комментарий */
- Имя переменной или функции может содержать только латинские буквы, цифры и знак подчёркивания, не может начинаться с цифры и совпадать с ключевыми словами языка
- Длина имён переменных, количество отступов и переносов строк не влияют на размер программы
- Инструкция заканчивается точкой с запятой
;
, одна инструкция в строке - Вызов функции осуществляется круглыми скобками -
foo()
- Блоки кода обрамляются фигурными скобками
{ код }