main — это функция, с которой начинается выполнение любой обычной программы на C++: операционная система передает управление именно в нее, а не в первую строку файла. Возвращаемый тип у нее всегда int, и по этому числу среда узнает, успешно ли завершилась программа.
Содержание
Ниже разберем, зачем нужна main, две ее стандартные формы записи, как через нее принять аргументы командной строки (argc и argv), что и зачем она возвращает, а также частые ошибки вроде void main(). Все примеры прогнаны компилятором, вывод в статье — реальный.
Что такое main и зачем она нужна
Когда вы запускаете скомпилированную программу, стартовый код рантайма готовит окружение и вызывает вашу main. Поэтому ровно одна main должна быть в программе: без нее компоновщик (линкер) выдаст ошибку и исполняемый файл не соберется.
Внутри main находится точка входа в вашу логику: отсюда вы вызываете другие функции, создаете объекты, читаете ввод. Когда main завершается, программа заканчивает работу и возвращает коду операционной системы число — признак успеха или ошибки.
У main есть ограничения, которых нет у обычных функций. Ее нельзя перегрузить, нельзя объявить inline, static или constexpr, и ее нельзя вызывать из самой программы, в том числе рекурсивно. Это единственная функция, точку входа в которую выбирает не программист, а среда исполнения.
Минимальный рабочий пример
Начнем с самой короткой полноценной программы. Ее можно скопировать в файл, скомпилировать и запустить:
#include <iostream>
int main() {
std::cout << "Hello, World!" << std::endl;
return 0;
}
Вывод программы:
Hello, World!
Разберем по строкам:
#include <iostream>подключает заголовочный файл стандартной библиотеки ввода-вывода — без него не будетstd::cout.int main()— объявление точки входа: тип возвратаint, имяmain, пустой список параметров.- Фигурные скобки
{ }ограничивают тело функции: открывающая — начало, закрывающая — конец. std::cout << "Hello, World!"выводит строку в консоль;std::endlдобавляет перевод строки и сбрасывает буфер.return 0;завершает программу с кодом 0 — признаком успешного выполнения.
Здесь std:: — это префикс пространства имен std, в котором лежат cout, endl и остальные средства стандартной библиотеки. Пространства имен нужны, чтобы имена из библиотеки не конфликтовали с вашими.
Две стандартные формы записи main
Стандарт C++ гарантирует поддержку ровно двух форм точки входа. Выбор между ними зависит от одного: нужны программе аргументы командной строки или нет.
| Форма записи | Когда выбирать |
|---|---|
int main() |
программе не нужны аргументы командной строки |
int main(int argc, char* argv[]) |
программа читает аргументы, переданные при запуске |
Обе формы равноправны, и обе обязаны поддерживаться в любой размещенной (hosted) среде. Параметры второй формы значат следующее:
argc(argument count) — число переданных аргументов, всегда не меньше 1.argv(argument vector) — массив строк с самими аргументами;argv[0]— имя или путь запуска программы, а последний элементargv[argc]равен нулевому указателю.
Проверим это на программе, которая печатает все аргументы:
#include <iostream>
int main(int argc, char* argv[]) {
std::cout << "argc = " << argc << "\n";
for (int i = 0; i < argc; ++i) {
std::cout << "argv[" << i << "] = " << argv[i] << "\n";
}
return 0;
}
Если запустить ее вообще без аргументов, argc равен 1, а единственный элемент argv[0] — путь, по которому стартовала программа:
argc = 1
argv[0] = /tmp/.../a.out
Путь у вас будет свой — это и есть argv[0]. Запустите ту же программу командой ./a.out one two, и вывод изменится: argc станет 3, argv[1] будет one, а argv[2] — two. Каждое слово после имени программы, разделенное пробелом, становится отдельным элементом argv.
Встречается и запись char** argv вместо char* argv[] — это то же самое: массив указателей на строки. Некоторые компиляторы разрешают и третий параметр (окружение), но он нестандартен, полагаться на него не стоит.
Что возвращает main
Тип int перед main — это не формальность: возвращаемое число получает операционная система или скрипт, запустивший программу. По соглашению 0 означает успех, любое ненулевое значение — ошибку. Это позволяет, например, в shell-скрипте проверить, отработала ли программа.
Чтобы не запоминать числа, в заголовке <cstdlib> есть две именованные константы — EXIT_SUCCESS и EXIT_FAILURE:
#include <iostream>
#include <cstdlib>
int main() {
std::cout << "EXIT_SUCCESS = " << EXIT_SUCCESS << "\n";
std::cout << "EXIT_FAILURE = " << EXIT_FAILURE << "\n";
// конец main без return: стандарт трактует это как return 0
}
Вывод программы:
EXIT_SUCCESS = 0
EXIT_FAILURE = 1
Обратите внимание: в этом примере нет строки return. У main есть особое правило — если выполнение доходит до закрывающей скобки без return, компилятор подставляет return 0; автоматически. Это работает только для main; в любой другой функции с типом int пропуск return приведет к неопределенному поведению.
Частые ошибки
Самая распространенная неверная запись — void main(). Ее иногда можно встретить в старых учебниках, но стандарт C++ ее не допускает:
#include <iostream>
void main() {
std::cout << "bad" << std::endl;
}
На современном компиляторе это не предупреждение, а ошибка компиляции — программа не соберется:
error: 'main' must return 'int'
Исправление простое — вернуть корректный тип и, при желании, явный код возврата:
#include <iostream>
int main() {
std::cout << "ok" << std::endl;
return 0;
}
Еще пара типичных заблуждений. main нельзя вызвать из своей же программы — попытка сделать рекурсивный вызов main() внутри тела запрещена стандартом. И main не участвует в перегрузке: две функции main с разными параметрами в одной программе — это ошибка, а не выбор подходящей версии.
Выводы
main— точка входа программы на C++: с нее операционная система начинает выполнение, и она должна быть в программе ровно одна.- Возвращаемый тип всегда
int; 0 (илиEXIT_SUCCESS) означает успешное завершение, ненулевое значение — ошибку. - Стандарт гарантирует две формы:
int main()без аргументов иint main(int argc, char* argv[])для чтения командной строки, гдеargc— число аргументов,argv— массив строк. - Если в
mainдойти до конца безreturn, компилятор сам подставитreturn 0— но только дляmain, не для других функций. void main()не соответствует стандарту; на строгих компиляторах это ошибка сборки. Такжеmainнельзя перегружать, вызывать рекурсивно и объявлятьinline,staticилиconstexpr.
Где применяется и что учить дальше
Правильно оформленная main — первое, с чего начинается любой проект на C++: от учебной консольной программы до утилиты, которая разбирает аргументы командной строки и возвращает осмысленный код завершения в CI-пайплайн. Понимание argc/argv и кодов возврата нужно, как только программа перестает быть одним Hello, World и начинает взаимодействовать с окружением.
Освойте тему на практике
Если хочется освоить C++ системно — от синтаксиса и точки входа до работы с памятью и стандартной библиотекой — посмотрите курс C++ Basic. Оценить формат и уровень до старта помогают бесплатные открытые уроки Otus — живые занятия с преподавателями.
Смежные темы: Функция main в семействе языков C.
FAQ
Можно ли писать int main(void) в C++, как в C? Да, это допустимо и означает то же самое, что int main() — функция без параметров. В C++ пустые скобки уже значат «без аргументов», поэтому void внутри избыточен, но ошибкой не является.
Почему в примерах иногда нет return 0, и программа все равно работает? Потому что для main язык делает исключение: при достижении конца функции без return подставляется return 0. Для наглядности и переносимости кода return 0; все же лучше писать явно.
Обязательно ли main должна быть в глобальном пространстве имен? Да. main должна быть свободной функцией в глобальной области; ее нельзя сделать методом класса или поместить в свое пространство имен — среда исполнения ищет ее именно как глобальную main.



