Разница между int main () и int main (void)?
что означает следующее:
int main(void) {...}
VS
int main() {...}
?
думаю, что int main() {...} означает, что main не получает никаких параметров (из командной строки), однако:
int main(int argc, char *argv[])
делает.
но что значит int main(void) {...} означает ? что значит пустота расшифровывается ?
Я посмотрел здесь, но это как-то другой вопрос .
8 ответов:
В C++ нет никакой разницы.
В C, разница сомнительна. Некоторые любят утверждать, что последняя версия (без
void) технически является просто общим расширением реализации и не гарантирует работу по стандарту из-за формулировки в стандарте. Однако в стандарте четко указано, что в определении функции пустой набор параметров, имеет четко определенные поведение: что функция не принимает никаких параметров. Таким образом такая определение для main соответствует следующему описанию в стандарте:Он [main] должен быть определен с возвращаемым типом int и без параметров.
существует, однако, заметная разница между ними: а именно, версия без
voidне удается предоставить правильный прототип для функции:// this is OK. int main() { if (0) main(42); } // this requires a diagnostic to be shown during compiling int main(void) { if (0) main(42); }О, и просто, чтобы быть полным:
voidимеет следующее значение во всех деклараторах функций:(6.7.6.3p10) частный случай неназванного параметра типа void в качестве единственного элемента в списке указывает, что функция не имеет параметров.
В C, в прототип (не в C++, хотя) пустой список аргументов означает, что функция может принимать любой аргументы (в определении функции, это означает отсутствие аргументов). В C++ пустой список параметров означает отсутствие аргументов. В C, чтобы не получить аргументы, вы должны использовать
void. Смотрите этой вопрос для лучшего объяснения.
в C++ есть функция
foo(void)иfoo()это одно и то же. Однако в C все по-другому:foo(void)- Это функция, которая не имеет никаких аргументов, в то время какfoo()- функция с неопределенными аргументами.
В C++ нет никакой разницы, оба одинаково.
оба определения также работают в C, но второе определение с void считается технически лучше, поскольку оно четко указывает, что main может быть вызван только без какого-либо параметра. В C, если сигнатура функции не указывает никакого аргумента, это означает, что функция может быть вызвана с любым количеством параметров или без каких-либо параметров. Например, попробуйте скомпилировать и запустить следующие две программы на C (не забудьте сохранить файлы .с.)
прежде всего, есть разница в том, что разрешено для размещенных систем и автономных систем, как показано здесь.
для размещенных систем, 5.1.2.2.1 запуск программы применяется:
функция, вызываемая при запуске программы, называется главным. Реализация объявляет нет прототип для этой функции. Он должен быть определен с типом возврата int и без параметры:
int main(void)... (далее следует текст что касается стилей argv / argc и т. д.).
интересная часть "без параметров".
int main()иint main (void)в настоящее время эквивалентны, так как они оба являются деклараторами функций и не имеют параметров. Применяется следующее (6.7.6.3):10 частный случай неназванного параметра типа void в качестве единственного элемента в списке указывает, что функция не имеет параметров.
/--/
14 список идентификаторов объявляет только идентификаторы параметров функции. пустой список в деклараторе функций, который является частью определения этой функции, указывает, что функция не имеет параметров. пустой список в деклараторе функций, который не является частью определение этой функции указывает, что нет информации о количестве или типах параметров входит в комплект поставки.145)
акцент мой, жирный текст-это то, что относится к
int main(). Есть также Примечание 145) на конец текста, в котором говорится "см." будущие языковые направления "(6.11.6)":функции 6.11.6 деклараторы
использование деклараторов функций с пустыми скобками (не деклараторы типа параметров прототип-формат) является устаревшей функцией.
и вот в чем разница. Будучи декларатором функций,
int main()и плохой стиль из-за вышеизложенного, так как он не гарантированно работает в следующей версии стандарт C. Он помечается как устаревшая функция в C11.поэтому вы должны всегда использовать
int main (void)на размещенной системе и никогдаint main(), даже если эти две формы на данный момент эквивалентны.
в C++ обе формы полностью эквивалентны, но есть
int main()является предпочтительным стилем по субъективным, косметическим причинам (так говорит Бьярне Страуструп... что, вероятно, является довольно плохим обоснованием для объяснения того, почему вы делаете что-то определенным образом).
В C++ нет никакой разницы между двумя, и
int main()- это юридическая подпись и тип возврата дляmain.
прототип функции, имеющий
Type foo(void)Это абсолютно то же самое, чтоType foo(), нет никакой разницы между ними. Первый может быть использован для удобства чтения.С
main- принимая аргументы или нет, программа все еще может получить доступ к информации командной строки с помощью других средств, таких как__argv,__argc,GetCommandLine, или другие специфичные для платформы/компилятора символы.
Я знаю, что нить старая, но этот вопрос беспокоил меня некоторое время несколько лет назад, поэтому я хотел бросить свои полцента(если это так).
Я всегда рассматриваю функции C, как если бы они имели фиксированное количество аргументов независимо от контекста, если они не используют va_args. То есть, я доверяю main, чтобы всегда иметь прототип:
int main(int argc, char **argv).даже если аргументы не передаются, функция имеет эти аргументы в стеке, потому что основная функция не имеет функции перегрузка.
C имеет возможность иметь примитивную перегрузку, просто притворяясь, что аргумента нет. В этом случае аргумент все еще передается и находится в стеке, но вы никогда не обращаетесь к нему, поэтому он просто уменьшает размер исходного кода.
говоря int main () просто означает, что я знаю, что функция может иметь параметры, но я не использую их, поэтому я пишу int main ().
говоря int main (void) говорит, что main, конечно, не имеет аргументов, и подразумевает, что существуют два разных прототипа функций:
int main(void); int main(int argc, char **argv);поскольку C не имеет перегрузки функций, это несколько вводит меня в заблуждение, и я не доверяю коду, который имеет main(void) в нем. Я бы не стал, если main никогда не принимал никаких параметров, и в этом случае main(void) будет полностью в порядке.
примечание: в некоторых реализациях есть больше параметров в main, чем argc и argv, таких как env, но это меня не беспокоит, потому что я знаю, что я явно не говорю, что это только два параметра, но это минимальные параметры, и это нормально иметь больше, но не меньше. Это в отличие от прямого высказывания int main (void), которое кричит на меня, поскольку эта функция не имеет параметров, что неверно, поскольку это так, они просто опущены.
вот мой базовый код:
/* sample.c - build into sample. */ #include <stdio.h> int main(void) { int _argc = *((int *)2686800); char ***_pargv = (char ***)2686804; int i; for (i = 1; i < _argc; ++i) { printf("%s ", (*_pargv)[i]); } return 0; }./ пример у меня явно есть аргументы
функция явно имеет аргументы, переданные ей, несмотря на то, чтобы явно сказать, что это не происходит путем ввода void в прототип функции.
как эквалайзер - говорит выше:
(6.7.6.3p10) частный случай неназванного параметра типа void в качестве единственный пункт в списке указывает, что функция не имеет параметров.
таким образом, говоря, что функция имеет void в качестве аргумента, но на самом деле имея аргументы в стеке является противоречием.
моя точка зрения заключается в том, что аргументы все еще существуют, поэтому явно утверждая то, что главное лишено аргументов-это нечестно. Честным способом было бы сказать int main(), который ничего не утверждает о том, сколько параметров у него есть, только о том, сколько параметров вы заботитесь.
NOTE2: _argc, _pargv зависят от системы, чтобы найти свои значения, вы должны найти их, запустив эту программу:
/* findargs.c */ #include <stdio.h> int main(int argc, char **argv) { printf("address of argc is %u.\n", &argc); printf("address of argv is %u.\n", &argv); return 0; }эти значения должны оставаться правильными для вашей конкретной системы.
Comments