Main()
В компьютерном программировании точка входа — это место в программе, где начинается выполнение программы и где программа имеет доступ к аргументам командной строки . [1]
Чтобы начать выполнение программы , загрузчик или операционная система передает управление ее точке входа. (Во время загрузки программой является сама операционная система). Это отмечает переход от времени загрузки (и времени динамической компоновки , если оно присутствует) ко времени выполнения .
Для некоторых операционных систем и языков программирования точкой входа является библиотека времени выполнения — набор функций поддержки языка. Код библиотеки инициализирует программу, а затем передает управление самой программе. В других случаях программа может сама инициализировать библиотеку времени выполнения. [2]
В простых системах выполнение начинается с первого оператора, что часто встречается в интерпретируемых языках , простых исполняемых форматах и загрузчиках . В других случаях точка входа находится по другому известному адресу памяти , который может быть абсолютным или относительным адресом ( смещение ).
Альтернативно, выполнение программы может начаться в именованной точке либо с обычным именем, определенным языком программирования или операционной системой, либо с именем, указанным вызывающей стороной. Во многих языках семейства C эта функция называется main
; в результате точку входа часто называют основной функцией . [3]
В языках JVM , таких как Java , точкой входа является статический метод, называемый main
; в языках CLI, таких как C#, точкой входа является статический метод с именем Main
. [4]
Точки входа применяются как к исходному коду, так и к исполняемым файлам. Однако при повседневной разработке программного обеспечения программисты указывают точки входа только в исходном коде, что делает их гораздо более известными. Точки входа в исполняемые файлы зависят от двоичного интерфейса приложения (ABI) фактической операционной системы и генерируются компилятором или компоновщиком (если это не исправлено ABI). Другие связанные объектные файлы также могут иметь точки входа, которые позже используются компоновщиком при создании точек входа исполняемого файла.
Точки входа способны передавать аргументы команды, переменные или другую информацию в качестве локальной переменной, используемой методом Main()
. Таким образом, определенные параметры могут быть установлены при выполнении программы, а затем интерпретированы программой. Многие программы используют это как альтернативный способ настройки различных параметров или выполнения набора различных действий с помощью одной программы.
В большинстве популярных сегодня языков программирования и операционных систем компьютерная программа обычно имеет только одну точку входа .
В программах C , C++ , D , Zig , Rust и Kotlin это функция с именем main
; в Java это статический метод с именем main
(хотя класс должен быть указан во время вызова), а в C# это статический метод с именем Main
. [5] [6]
Во многих основных операционных системах стандартный формат исполняемого файла имеет единственную точку входа. В исполняемом и связываемом формате (ELF), используемом в Unix и Unix-подобных системах, таких как Linux , точка входа указывается в e_entry
поле заголовка ELF. В коллекции компиляторов GNU (gcc) точкой входа, используемой компоновщиком, является символ _start
. Аналогично, в формате Portable Executable , используемом в Microsoft Windows , точка входа указывается полем AddressOfEntryPoint
, унаследованным от COFF . В COM-файлах точка входа находится по фиксированному смещению 0100h.
Единственным исключением из парадигмы единой точки входа является Android . Приложения Android не имеют единой точки входа — нет специальной main
функции. Вместо этого у них есть важные компоненты (действия и службы), которые система может загружать и запускать по мере необходимости. [7]
Иногда используемый метод — это «толстый двоичный файл» , который состоит из нескольких исполняемых файлов для разных целей, упакованных в один файл. Чаще всего это реализуется с помощью одной общей точки входа, которая совместима со всеми целями и ветвями к конкретной целевой точке входа. Альтернативные методы включают хранение отдельных исполняемых файлов в отдельных форках , каждый со своей собственной точкой входа, которая затем выбирается операционной системой.
Исторически сложилось так, что в некоторых современных устаревших системах , таких как VMS и OS/400 , компьютерные программы имеют множество точек входа , каждая из которых соответствует различным функциям программы. Обычный способ обозначения точек входа, используемый в масштабе всей системы в VMS, а также в программах PL/I и MACRO , состоит в добавлении их в конец имени исполняемого образа, разделенного знаком доллара ($), например directory.exe$make
.
Компьютер Apple I также в некоторой степени использовал это. Например, альтернативная точка входа в BASIC Apple I сохранит полезность программы BASIC при случайном нажатии кнопки сброса. [ нужны разъяснения ]
В общем, программы могут выйти в любой момент, вернувшись в операционную систему или вылетев . Программы на интерпретируемых языках возвращают управление интерпретатору, но программы на скомпилированных языках должны возвращаться операционной системе, иначе процессор просто продолжит выполнение после окончания программы, что приведет к неопределенному поведению .
Обычно в программе не указывается ни одна точка выхода. Однако в других случаях среда выполнения гарантирует, что программы всегда завершаются структурированным образом через единственную точку выхода, что гарантировано, если только сама среда выполнения не выйдет из строя; это позволяет запускать код очистки, например atexit
обработчики. Это можно сделать, потребовав, чтобы программы завершали работу путем возврата из основной функции, путем вызова определенной функции выхода, или путем перехвата исключений или сигналов операционной системы во время выполнения.
Во многих языках программирования main
функция — это место, с которого программа начинает свое выполнение. Он обеспечивает высокоуровневую организацию функциональности программы и обычно имеет доступ к аргументам команды , передаваемым программе при ее выполнении.
Основная функция обычно является первой функцией , написанной программистом , которая запускается при запуске программы и вызывается непосредственно из системной инициализации, содержащейся в среде выполнения ( crt0 или эквивалент). Однако некоторые языки могут выполнять написанные пользователем функции перед основным выполнением, например конструкторы глобальных объектов C++ .
В других языках, особенно во многих интерпретируемых языках , выполнение начинается с первого оператора программы.
Ниже приводится неисчерпывающий список языков программирования, описывающий способ определения основной точки входа:
В APL при загрузке рабочей области содержимое переменной «quad LX» (скрытое выражение) интерпретируется как выражение APL и выполняется.
В C и C++ прототип функции main выглядит следующим образом:
ИНТ основной ( недействительный ); инт основной (); int main ( int argc , char ** argv ); int main ( int argc , char * argv []); int main ( int argc , char ** argv , char ** env ); // точнее в C // НЕ в соответствии со стандартом ISO C 5.1.2.2.1 // НО во встроенном программировании в зависимости от микроСи эта форма также используется void main ( void );
Основная функция выглядит как точка входа для программистов приложений (точка входа приложения или основная точка входа). Системное программирование раскрывает дополнительную информацию о программе и указывает точку входа в другом месте (в процедуре инициализации или в векторе прерывания сброса для автономных программ).
Параметры , количество аргументов и вектор аргументов , [ 8 ] соответственно задают количество и значения аргументов командной строки программы . Имена и могут быть любыми допустимыми идентификаторами в C, но использование этих имен является общепринятым. В C++ имена следует понимать буквально, а «void» в списке параметров следует опускать, если требуется строгое соответствие. [9] Другие форматы, зависящие от платформы, также разрешены стандартами C и C++, за исключением того, что в C++ тип возвращаемого значения всегда должен быть ; [10] например, Unix (но не POSIX.1 ) и Windows имеют третий аргумент, указывающий среду программы , в противном случае доступную через in :argc
argv
argc
argv
int
getenv
stdlib.h
int main ( int argc , char ** argv , char ** envp );
Операционные системы на основе Дарвина , такие как macOS , имеют четвертый параметр, содержащий произвольную информацию, предоставляемую ОС, например путь к исполняемому двоичному файлу: [11]
int main ( int argc , char ** argv , char ** envp , char ** apple );
Значение, возвращаемое основной функцией, становится статусом завершения процесса, хотя стандарт C придает конкретное значение только двум значениям: EXIT_SUCCESS
(традиционно 0) и EXIT_FAILURE
. Значение других возможных возвращаемых значений определяется реализацией. Если возвращаемое значение не определено программистом, компилятор вставляет неявное значение return 0;
в конец функции ; main()
такое поведение требуется стандартом C++.
Гарантируется, что argc
он неотрицательен и argv[argc]
является нулевым указателем . По соглашению аргументы командной строки, заданные argc
и argv
включают имя программы в качестве первого элемента, если argc
оно больше 0; если пользователь вводит команду " rm file
", оболочка инициализирует rm
процесс с помощью argc = 2
и argv = {"rm", "file", NULL}
. Как argv[0]
и имя, под которым появляются процессы в и ps
т top
. д., некоторые программы, такие как демоны или программы, работающие в интерпретаторе или виртуальной машине (где argv[0]
будет имя исполняемого файла хоста), могут изменить свой argv, чтобы предоставить более описательный argv[0]
, обычно посредством exec
системного вызова.
Функция main()
особенная; обычно каждая программа C и C++ должна определять его ровно один раз.
Если объявлено, main()
оно должно быть объявлено так, как если бы оно имело внешнюю ссылку; его нельзя объявить static
или inline
.
В C++ main()
должно находиться в глобальном пространстве имен (т. е ::main
.), не может быть перегружено и не может быть функцией-членом , хотя имя иначе не зарезервировано и может использоваться для функций-членов, классов, перечислений или функций, не являющихся членами в другие пространства имен. В C++ (в отличие от C) main()
нельзя вызывать рекурсивно и нельзя получить его адрес.
При выполнении программы, написанной на C# , CLR ищет статический метод, отмеченный .entrypoint
директивой IL, который либо не принимает аргументов, либо имеет один аргумент типа string[]
и имеет возвращаемый тип void
или int
, и выполняет его. [12]
статическая пустота Main (); статическая сила Main ( строка [] args ); статический int Main (); static int Main ( string [] args );
Аргументы командной строки передаются в args
, аналогично тому, как это делается в Java. Для версий Main()
возврата целого числа, аналогичных C и C++, оно передается обратно в среду как статус завершения процесса.
Начиная с C#7.1 существует еще четыре возможных сигнатуры точки входа, которые позволяют асинхронное выполнение в Main()
методе. [13]
static async Task Main () static async Task < int > Main () static async Task Main ( string []) static async Task < int > Main ( string [])
Типы Task
and Task<int>
являются асинхронными эквивалентами void
и int
. async
требуется, чтобы разрешить использование асинхронности ( await
ключевого слова) внутри метода.
Clean — функциональный язык программирования, основанный на переписывании графов. Начальный узел имеет имя Start
и тип, *World -> *World
если он меняет мир, или какой-то фиксированный тип, если программа печатает результат только после сокращения Start
.
Старт :: * Мир -> * Мир Старт мира = startIO ...
Или даже проще
Start :: String Start = "Привет, мир!"
Один сообщает компилятору, какую опцию использовать для создания исполняемого файла.
ANSI Common Lisp не определяет главную функцию; вместо этого код читается и оценивается сверху вниз в исходном файле. Однако следующий код будет эмулировать функцию main.
( defun hello-main () ( format t "Hello World!~%" )) ( привет-главный )
В D прототип функции main выглядит следующим образом:
пустая функция (); void main ( строка [] args ); инт основной (); int main ( строка [] args );
Аргументы командной строки передаются в args
, аналогично тому, как это делается в C# или Java. Для версий main()
возврата целого числа, аналогичных C и C++, оно передается обратно в среду как статус завершения процесса.
Dart — это язык программирования общего назначения , который часто используется для создания веб-приложений и мобильных приложений. Как и во многих других языках программирования, в Dart есть точка входа, которая служит отправной точкой для программы Dart. Точка входа — это первая функция, которая выполняется при запуске программы. В Dart точкой входа обычно является функция с именем main
. Когда запускается программа Dart, среда выполнения Dart ищет функцию с именем main
и выполняет ее. Любой код Dart, который должен выполняться при запуске программы, должен быть включен в main
функцию. Вот пример простой main
функции в Dart:
void main () { print ( "Привет, мир!" ); }
В этом примере main
функция просто выводит текст Hello, world!
на консоль при запуске программы. Этот код будет выполняться автоматически при запуске программы Dart.
Важно отметить, что хотя эта main
функция является точкой входа по умолчанию для программы Dart, при необходимости можно указать другую точку входа. Это можно сделать с помощью @pragma("vm:entry-point")
аннотации в Dart. Однако в большинстве случаев main
функция является точкой входа, которую следует использовать для программ Dart.
В FORTRAN нет основной подпрограммы или функции. Вместо этого PROGRAM
можно использовать оператор в первой строке, чтобы указать, что программный модуль является основной программой, как показано ниже. Этот PROGRAM
оператор нельзя использовать для рекурсивных вызовов. [14]
ПРОГРАММА HELLO PRINT * , "Cint!" КОНЕЦ ПРОГРАММЫ ПРИВЕТ
Некоторые версии Фортрана, например версии IBM System/360 и последующих мэйнфреймов, не поддерживают оператор PROGRAM. Многие компиляторы других производителей программного обеспечения позволяют компилировать программу на языке Фортран без оператора PROGRAM. В этих случаях любой модуль, который имеет какой-либо оператор без комментариев, в котором не встречается оператор SUBROUTINE, FUNCTION или BLOCK DATA, считается основной программой.
Используя GNAT , программисту не требуется писать функцию с именем main
; исходный файл, содержащий одну подпрограмму, может быть скомпилирован в исполняемый файл. Однако связыватель создаст пакет ada_main
, который будет содержать и экспортировать основную функцию в стиле C.
В языке программирования Go выполнение программы начинается с main
функцииpackage main
пакет основной импортировать "ФМТ" func main () { fmt . Println ( «Привет, мир!» ) }
Невозможно получить доступ к аргументам или коду возврата за пределами стандартной библиотеки Go. Доступ к ним можно получить через os.Args
и os.Exit
соответственно, оба из которых включены в "os"
пакет.
Программа на Haskell должна содержать имя, main
привязанное к значению типа IO t
для некоторого типа t
; [15] что обычно IO ()
. IO
— это монада , которая организует побочные эффекты в виде чисто функционального кода. [16] Значение main
представляет собой вычисления с учетом побочных эффектов, выполняемые программой. Результат вычисления, представленный main
отбрасывается; поэтому main
обычно имеет тип IO ()
, который указывает, что тип результата вычисления — ()
тип единицы , который не содержит никакой информации.
main :: IO () main = putStrLn "Привет, Мир!"
Аргументы командной строки не передаются main
; их необходимо получить с помощью другого действия ввода-вывода, например System.Environment.getArgs
.
Программы Java начинают выполняться с основного метода класса, [17] [18] [19] [20] , который имеет один из следующих заголовков методов :
public static void main ( String [] args ) public static void main ( String ... args ) public static void main ( String args [] ) void main ()
Аргументы командной строки передаются в формате args
. Как и в C и C++, имя " main()
" является особенным. Основные методы Java не возвращают значение напрямую, но его можно передать с помощью метода System.exit()
.
В отличие от C, имя программы не включается в args
, поскольку это имя класса, содержащего основной метод, поэтому оно уже известно. Кроме того, в отличие от C, количество аргументов включать не нужно, поскольку массивы в Java имеют поле, которое отслеживает количество элементов.
Основная функция должна быть включена в класс. Это потому, что в Java все должно содержаться в классе. Например, программа hello world на Java может выглядеть так:
общественный класс HelloWorld { public static void main ( String [] args ) { System . вне . println ( "Привет, мир!" ); } }
Чтобы запустить эту программу, необходимо вызвать java HelloWorld
каталог, в котором находится файл скомпилированного класса HelloWorld.class
. Альтернативно, исполняемые файлы JAR используют файл манифеста для указания точки входа способом, независимым от файловой системы с точки зрения пользователя.
В FMSLogo процедуры при загрузке не выполняются. Чтобы заставить их выполниться, необходимо использовать этот код:
прокнамить ... ; Команды запуска (например, print [Добро пожаловать])конец
сделать "запуск [procname]
Переменная startup
используется для запуска списка действий, но соглашение заключается в том, что она вызывает процедуру, которая запускает действия. Эта процедура может иметь любое имя.
OCaml не имеет main
функции. Программы оцениваются сверху вниз.
Аргументы командной строки доступны в массиве с именем Sys.argv
, а статус выхода по умолчанию равен 0.
Пример:
print_endline «Привет, мир»
В языке Паскаль основная процедура — это единственный безымянный блок в программе. Поскольку программы на языке Pascal определяют процедуры и функции в более строгом порядке снизу вверх, чем программы на C, C++ или Java, основной процедурой обычно является последний блок программы. В Паскале нет особого значения для имени " main
" или любого подобного имени.
программа Hello ( Вывод ) ; начать writeln ( 'Привет, мир!' ) ; конец .
Аргументы командной строки учитываются ParamCount
и доступны в виде строк ParamStr(n)
с помощью n от 0 до ParamCount
.
Версии Pascal, поддерживающие модули или модули, также могут содержать в каждой из них безымянный блок, который используется для инициализации модуля. Эти блоки выполняются до вызова основной точки входа в программу.
В Perl нет функции main. Операторы выполняются сверху вниз, хотя операторы в BEGIN
блоке выполняются раньше обычных операторов.
Аргументы командной строки доступны в специальном массиве @ARGV
. В отличие от C, @ARGV
не содержит имени программы, то есть $0
.
PHP не имеет «основной» функции. Начиная с первой строки PHP-скрипта, любой код, не инкапсулированный заголовком функции, выполняется, как только он виден.
Синтаксис в Pike аналогичен синтаксису C и C++. Исполнение начинается в main
. Переменная " argc
" хранит количество аргументов , переданных программе. Переменная " argv
" содержит значение, связанное с аргументами, передаваемыми программе.
Пример:
int main ( int argc , массив ( строка ) argv )
Программы Python оцениваются сверху вниз, как это обычно бывает в языках сценариев: точкой входа является начало исходного кода. Поскольку определения должны предшествовать использованию, программы обычно имеют структуру с определениями вверху и кодом для выполнения внизу (без отступов), аналогично коду для однопроходного компилятора , такого как в Pascal.
В качестве альтернативы, программа может быть структурирована с помощью явной main
функции, содержащей код, который будет выполняться при непосредственном выполнении программы, но который также может быть вызван путем импорта программы как модуля и вызова функции. Это можно сделать с помощью следующей идиомы, которая предполагает, что внутренняя переменная __name__
устанавливается __main__
при выполнении программы, а не при ее импорте как модуль (в этом случае вместо этого ей присваивается имя модуля); существует множество вариантов этой структуры: [21] [22] [23]
импортировать системуdef main ( argv ): n = int ( argv [ 1 ]) print ( n + 1 )если __name__ == '__main__' : sys . выход ( основной ( sys . argv ))
В этой идиоме вызов именованной точки входа main
является явным, а взаимодействие с операционной системой (получение аргументов, вызов выхода из системы) осуществляется явно посредством вызовов библиотеки, которые в конечном итоге обрабатываются средой выполнения Python. Это контрастирует с C, где это делается неявно во время выполнения, на основе соглашения.
В языке QB64 нет основной функции, сначала выполняется код, не входящий в функцию, или подпрограмма, сверху вниз:
напечатать «Привет, мир! a =" ; a = getInteger ( 1.8 d ): напечатайте a
функция getInteger ( n как double ) getInteger = int ( n ) конечная функция
Аргументы командной строки (если есть) можно прочитать с помощью функции COMMAND$ :
общая командная строка dim как строка командная строка = COMMAND$
'Несколько аргументов командной строки, разделенных пробелами, можно прочитать с помощью COMMAND$(n) commandline1 = COMMAND$ ( 2 )
В Ruby нет отдельной основной функции. Вместо этого код, написанный вне любой области class .. end
или, module .. end
выполняется в контексте специального " main
" объекта. Доступ к этому объекту можно получить с помощью self
:
irb(main):001:0> self => main
Он имеет следующие свойства:
irb(main):002:0> self . class => Object irb(main):003:0> self . сорт . предки => [Объект, Ядро, БазовыйОбъект]
Методы, определенные вне области class
или module
, определяются как частные методы объекта " main
". Поскольку класс " main
" есть Object
, такие методы становятся частными методами почти каждого объекта:
irb(main):004:0> def foo irb(main):005:1> 42 irb(main):006:1> end => nil irb(main):007:0> foo => 42 irb(main): ):008:0> []. foo NoMethodError: частный метод `foo' вызван для []:Array from (irb):8 from /usr/bin/irb:12:in `<main>' irb(main):009:0> false . foo NoMethodError: частный метод `foo' вызван для false:FalseClass из (irb):9 из /usr/bin/irb:12:in `<main>'
Количество и значения аргументов командной строки можно определить с помощью ARGV
массива констант:
$ irb /dev/tty foo bartty(main):001:0> ARGV ARGV => ["foo", "bar"] tty(main):002:0> ARGV.size ARGV.size => 2
Первый элемент ARGV
, ARGV[0]
, содержит первый аргумент командной строки, а не имя выполняемой программы, как в C. Имя программы можно получить, используя $0
или $PROGRAM_NAME
. [24]
Подобно Python, можно использовать:
if __FILE__ == $PROGRAM_NAME # Поместите здесь "основной" код в конце
выполнить некоторый код только в том случае, если его файл был указан при ruby
вызове.
В Rust точкой входа в программу является функция с именем main
. Обычно эта функция находится в файле с именем main.rs
или lib.rs
.
// В `main.rs` fn main () { println! ( "Привет, мир!" ); }
Кроме того, начиная с Rust 1.26.0, функция main может возвращать Result
: [25]
fn main () -> Result < (), std :: io :: Error > { println! ( "Привет, мир!" ); Ok (()) // Возвращает тип «Result» со значением «Ok» с содержимым «()», т. е. пустой кортеж. }
При запуске в Xcode Playground [26] Swift ведет себя как язык сценариев, выполняя операторы сверху вниз; разрешен код верхнего уровня.
// HelloWorld.playgroundlet hello = «привет» let world = «мир»let helloWorld = привет + " " + мирprint ( helloWorld ) // здравствуй, мир
Приложения на основе Cocoa и Cocoa Touch , написанные на Swift, обычно инициализируются с атрибутами @NSApplicationMain
и @UIApplicationMain
соответственно. Эти атрибуты по своему назначению эквивалентны файлу main.m
в проектах Objective-C : они неявно объявляют main
функцию, которая вызывает UIApplicationMain(_:_:_:_:)
[27] , которая создает экземпляр UIApplication
. [28]
Следующий код — это способ по умолчанию инициализировать iOS - приложение на базе Cocoa Touch и объявить его делегата приложения.
// AppDelegate.swiftимпортировать UIKit@UIApplicationMain класс AppDelegate : UIResponder , UIApplicationDelegate { окно вар : UIWindow ? func application ( _ application : UIApplication , DidFinishLaunchingWithOptions launchOptions : [ UIApplication . LaunchOptionsKey : Any ]?) -> Bool { return true } }
В Visual Basic , когда проект не содержит форм, объектом запуска может быть процедура Main()
. Эту Command$
функцию можно дополнительно использовать для доступа к аргументной части командной строки, используемой для запуска программы:
Подглавная ( ) Отладка . Распечатать «Привет, мир!» MsgBox "Аргументы, если таковые имеются: " & Command $ End Sub
В Xojo есть два разных типа проектов, каждый со своей основной точкой входа. Настольные приложения (GUI) запускаются с App.Open
событием объекта проекта Application
. Консольные приложения запускаются с App.Run
событием объекта проекта ConsoleApplication
. В обоих случаях основная функция генерируется автоматически и не может быть удалена из проекта.
В классе HelloWorld мы объявляем единственный метод main(), который, в свою очередь, содержит единственный вызов метода для отображения строки «Hello world!»
на стандартном выходе.
Оператор, который печатает «Hello world!»
делает это, вызывая метод println объекта out.
Объект out — это переменная класса в классе System, которая выполняет операции вывода над файлами.
//JAVA-программа начинается с вызова main().
В Java каждая строка кода, которая действительно может выполняться, должна находиться внутри класса.
«public class Main {}» объявляет класс с именем Main, который является общедоступным, что означает, что любой другой класс может получить к нему доступ.
«public static void main(String[] args) {}» — это точка входа в нашу Java-программу. основной метод должен иметь именно эту сигнатуру, чтобы иметь возможность запускать нашу программу.
{{cite web}}
: Внешняя ссылка |postscript=
( помощь )CS1 maint: постскриптум ( ссылка )ARGV