Во многих языках, таких как C, C ++ и Java, main
метод / функция имеет возвращаемый тип void
или int
, но не double
или String
. Какие могут быть причины этого?
Я немного знаю, что мы не можем этого сделать, потому что он main
вызывается из библиотеки времени выполнения, и он ожидает некоторый синтаксис, такой int main()
или int main(int,char**)
около того, что мы должны придерживаться этого.
Итак, мой вопрос: почему у него main
есть сигнатура типа, а не другая?
Ответы:
Возвращаемое значение
main
должно передаваться в операционную систему ( любую операционную систему) одним последовательным способом. Информация, которую должна знать операционная система: «Программа успешно завершилась или произошла ошибка?»Если это строка, ответ становится трудным на разных языках. Внутренние элементы строки Паскаля (первый байт равен длине) и строка FORTRAN (фиксированная, дополненная некоторым значением) и строка C (завершенная нулем) - все разные. Это усложнит возвращение непротиворечивого значения операционной системе. Предполагая, что это было решено, что бы вы сделали, чтобы ответить на вопрос, который была у ОС программы? Сравнение строк чревато ошибками («успех» или «успех»), и, хотя ошибка может быть более полезной для человека, для операционной системы или другой программы (оболочки) труднее иметь дело. Также были значительные различия даже в самих строках - EBCDIC (со всеми его кодовыми страницами) и ASCII.
Число с плавающей запятой и двойное число не предоставляют дополнительного значения по сравнению с целым числом для обратной передачи данных в ОС (и оболочку). По большей части, ни одна из этих частей компьютера не имеет дело с числами с плавающей запятой. Двойники также не перечисляются, что затрудняет сравнение. Не будучи перечисляемыми, они создают отчет об ошибке (при условии, что вы выбрали конкретное значение для успеха). Опять же, числа с плавающей запятой не согласованы - число с плавающей запятой на 8-битной машине отличалось от числа с плавающей запятой на 16-битной и 32-битной машине (и это только «нормальные» значения - даже в IBM плавающая точка не была стандартизирована между машинами одного и того же производителя до 1980-х годов). И тогда у вас есть десятичные против двоичных компьютеров. Значения с плавающей запятой не согласованы и не дают значимых данных обратно.
Это действительно оставляет нас с байтом и целым числом в качестве параметров. Соглашение, которое было установлено, было «0», было успехом, и все остальное было ошибкой. Целое число дает больше места, чем байт, для сообщения об ошибке. Он может быть перечислен (возврат 1 означает XYZ, возврат 2 означает ABC, возврат 3, означает DEF и т. Д.) Или может быть использован как флаг (
0x0001
означает, что это не удалось,0x0002
означает, что произошел сбой,0x0003
означает и то, и другое). Ограничение всего лишь одним байтом может легко исчерпать флаги (только 8), поэтому решение, вероятно, заключалось в использовании целого числа.источник
main()
вызывается по-разному в разных операционных системах. В C как изначально вызывается метод main ()? идет в это.main
- в отличие от других функций в любой программе - это не часть протокола, определенного программистом, а протокол, используемый для взаимодействия с хостом (ОС). Вы не можете выбрать это, потому что это никогда не было вашим выбором. На более прагматичном уровне UNIX ожидает, что процесс вернет int, и протокол C-to-UNIX делает именно это. Аналогичный аргумент может быть сделан для передачи аргументов: если бы C был изобретен для ОС / хоста, который передавал только числа в качестве аргументов (например, без командной строки), аргументы были бы целыми числами вместо строк.Ну, это может .
Например, на диалекте C, используемом в операционной системе Plan 9
main
, обычно объявляется какvoid
функция, но состояние выхода возвращается в вызывающую среду путем передачи строкового указателя наexits()
функцию. Пустая строка обозначает успех, а любая непустая строка обозначает какой-то сбой. Это может быть реализовано при наличииmain
возвращатьchar*
результат.И, конечно, было бы возможно реализовать систему со статусом
float
илиdouble
выход.Так почему же
int
? Это просто вопрос соглашения - и есть огромная ценность в том, чтобы операционные системы и программы, работающие под ними, подчинялись общему соглашению.Соглашение Unix состоит в том, чтобы использовать целочисленный код состояния, где 0 означает успех, а ненулевое - отказ (потому что обычно есть только один способ добиться успеха, но несколько способов потерпеть неудачу). Я не знаю, возникла ли эта конвенция с Unix; Я подозреваю, что это произошло от более ранних операционных систем.
Соглашение с плавающей точкой будет более сложным соглашением, поскольку (а) поддержка с плавающей точкой не является универсальной, (б) сложнее определить отображение между значениями с плавающей точкой и условиями ошибки, (в) разные системы используют разные плавающие представление точек и (d) просто представьте себе удовольствие от отслеживания ошибки округления в состоянии выхода вашей программы. Целые числа, с другой стороны, очень хорошо подходят для перечисления кодов ошибок.
В Plan 9, как я уже упоминал, используются строки, но это усложняет управление памятью, кодировку символов и т. Д. Насколько мне известно, идея, появившаяся в Plan 9, была новой, и она не заменила существующую. широко распространенная конвенция.
(Между прочим, в C ++
main
можно только возвращатьint
, а в Cvoid main
это разрешено только в том случае, если компилятор специально его поддерживает. Многие компиляторы не очень громко жалуются, если вы пишетеvoid main
, но это лишь небольшое преувеличение, чтобы сказать, что это неправильно .)источник
Значение, возвращаемое методом main, является «кодом выхода». Он используется приложением вызывающей стороны (обычно bash) для проверки, закончилась ли программа ожидаемым образом. Возврат целого числа - это самый простой способ сделать это на уровне ОС. Double не имеет смысла для кода ошибки, а String трудно поддерживать на уровне ОС (GC отсутствует).
источник
Функция main должна возвращать статус программы, которая выполняется. Независимо от того, выполняется ли она успешно (возвращает 0, то есть EXIT_SUCCESS) или нет (возврат 1 означает EXIT_FAILURE), любое ненулевое число передает то же значение, но ноль указывает на отсутствие ошибок или успешного выполнения.
источник