Разница между 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 etc).
интересная часть- "без параметров". int main()
и int main (void)
в настоящее время эквивалентны, поскольку они оба являются деклараторами функций и не имеют параметров. Применяется следующее (6.7.6.3):
10 частный случай неназванного параметра типа void в качестве единственного элемента в списке указывает, что функция не имеет параметров.
/--/
14 список идентификаторов объявляет только идентификаторы параметров функции. пустой список в деклараторе функций, который является частью определения этой функции, указывает, что функция не имеет параметров. пустой список в деклараторе функций, который не является частью определение этой функции указывает, что нет информации о количестве или типах параметры поставлены.145)
акцент мой, жирный текст-это то, что относится к int main()
. Также отметим, 145) на конец текста, в котором говорится "см." будущие языковые направления " (6.11.6)":
функции 6.11.6 деклараторы
использование деклараторов функций с пустыми скобками (а не деклараторов типов параметров прототипа) является устаревшей функцией.
и вот в чем разница. Будучи декларатором функций,int main()
is плохой стиль из-за вышеизложенного, так как не гарантируется работа в следующей версии стандарт 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 в прототип функции.
как eq-говорит выше:
(6.7.6.3p10) частный случай неназванного параметра типа void как единственный пункт в списке указывает, что функция не имеет параметров.
таким образом, говоря, что функция имеет void в качестве аргумента, но фактически имеет аргументы в стеке, является противоречием.
моя точка зрения заключается в том, что аргументы все еще существуют, поэтому явно утверждая то, что main не имеет аргументов, нечестно. Честным способом было бы сказать 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;
}
эти значения должны оставаться правильными для вашей конкретной системы.