Подтвердить что ты не робот

Разница между int main() и int main (void)?

Что означает следующее:

int main(void) {...} 

VS

int main() {...}

?

Я думаю, что int main() {...} означает, что main не получает никаких параметров (из командной строки):

int main(int argc, char *argv[])

делает.

Но что означает int main(void) {...}? что означает void?

Я посмотрел здесь, но это как-то другой вопрос.

4b9b3361

Ответ 1

В С++ нет разницы.


В C разница сомнительна. Некоторым нравится утверждать, что последняя версия (без void) технически является просто общим расширением реализации и не гарантируется работой по стандарту из-за формулировки в стандарте. Однако в стандарте четко указано, что в определении функции пустой набор параметров имеет четко определенное поведение: функция не принимает никаких параметров. Таким образом, такое определение для основного соответствует следующему описанию в стандарте:

Он [основной] должен быть определен с типом возврата 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 как единственного элемента в списке указывает, что функция не имеет параметров.

Ответ 2

В C, в прототипе (не в С++ хотя) пустой список аргументов означает, что функция может принимать любые аргументы (в определении функции это означает отсутствие аргументов). В С++ пустой список параметров означает отсутствие аргументов. В C, чтобы не принимать аргументов, вы должны использовать void. См. этот вопрос для лучшего объяснения.

Ответ 3

В С++, имеющем функцию foo(void) и foo(), это одно и то же. Однако в C это другое: foo(void) - это функция, которая не имеет аргументов, а foo() - это функция с неопределенными аргументами.

Ответ 4

В С++ нет разницы, оба одинаковы.

Оба определения работают и на C, но второе определение с void считается технически лучше, поскольку оно ясно указывает, что main можно вызывать только без какого-либо параметра. В C, если сигнатура функции не указывает какой-либо аргумент, это означает, что функция может вызываться с любым количеством параметров или без каких-либо параметров. Например, попытайтесь скомпилировать и запустить следующие две программы C (не забудьте сохранить ваши файлы как .c).

Ответ 5

Прежде всего, существует разница в том, что разрешено для размещенных систем и автономных систем, как показанных здесь.

Для размещенных систем, 5.1.2.2.1 применяется запуск программы:

Функция, вызванная при запуске программы, называется main. Реализация не объявляет прототип для этой функции. Он определяется с типом возврата 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(), даже если эти две формы на данный момент эквивалентны.


В С++ обе формы полностью эквивалентны, но там int main() является предпочтительным стилем для субъективных, косметических соображений (Bjarne Stroustrup говорит так... что, вероятно, довольно плохое объяснение, почему вы делаете что-то определенным образом).

Ответ 6

В С++ нет разницы между двумя, а int main() - это законная подпись и тип возврата для main.

Ответ 7

Прототип функции Type foo(void) абсолютно такой же, как Type foo(), между ними нет никакой разницы. Бывший может быть использован для удобства чтения.

Как и при использовании main - принятия аргументов или нет, программа все равно может обращаться к информации о командной строке с помощью других средств, таких как __argv, __argc, GetCommandLine или других символов платформы/компилятора.

Ответ 8

Я знаю, что поток старый, но несколько лет назад этот вопрос беспокоил меня, поэтому я хотел бросить свою половину процента (если это).

Я всегда рассматриваю функции C, как если бы они фиксировали количество аргументов независимо от контекста, если только они не используют va_args. То есть, я верю, что ВСЕГДА имеют прототип:

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 не имеет функции перегрузки, это несколько вводит меня в заблуждение, и я не доверяю коду с основным (void) в нем. Я бы не стал, если main NEVER принял какие-либо параметры, и в этом случае main (void) будет полностью в порядке.

ПРИМЕЧАНИЕ. В некоторых реализациях есть больше параметров в основном, чем 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;
}

./sample У меня явно есть аргументы

У функции явно есть аргументы, переданные ей, несмотря на то, что она явно не говорит о том, что она не набирает void в прототип функции.

Как указано выше:

(6.7.6.3p10) Частный случай неименованного параметра типа void как только элемент в списке указывает, что функция не имеет параметров.

Таким образом, говоря, что функция имеет пустоту как аргумент, но фактически наличие аргументов в стеке является противоречием.

Моя точка зрения заключается в том, что аргументы все еще существуют, поэтому явное утверждение о том, что main не содержит аргументов, является нечестным. Честным способом было бы сказать int main(), который не утверждает ничего о том, сколько параметров у него есть, только о том, сколько параметров вам нужно.

ПРИМЕЧАНИЕ2: _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;
}

Эти значения должны оставаться правильными для вашей конкретной системы.