Поведение вашей программы не определено, потому что вы определяете printOut()
без параметров, но вызываете его с одним аргументом.Вы должны это исправить.Но вы написали это так, что компилятору не требуется диагностировать проблему.(gcc, например, не предупреждает о несоответствии параметров, даже с -std=c99 -pedantic -Wall -Wextra
-O3.)
Причины этого исторические.
До ANSI C (до1989) не было прототипов;Объявления функций не могут указывать ожидаемый тип или количество аргументов.Функция definition , с другой стороны, задала параметры функции, но не так, чтобы компилятор мог использовать ее для диагностики несовпадающих вызовов.Например, функция с одним параметром int может быть объявлена (скажем, в файле заголовка) следующим образом:
int plus_one();
и определена (скажем, в соответствующем файле .c) следующим образом:
int plus_one(n)
int n;
{
return n + 1;
}
Информация о параметрах была скрыта внутри определения.
ANSI C добавил прототипы, поэтому приведенное выше можно записать так:
int plus_one(int n);
int plus_one(int n)
{
return n + 1;
}
Но язык продолжал поддерживатьобъявления и определения в старом стиле, чтобы не нарушать существующий код.Даже будущий стандарт C201X по-прежнему допускает объявления и определения функций до ANSI, хотя они устарели уже 22 года.
В вашем определении:
void printOut()
{
...
}
вы используетеопределение функции старого стиля.Он говорит, что у printOut нет параметров - но он не позволяет компилятору предупреждать вас, если вы вызываете его неправильно.Внутри вашей функции вы вызываете ее с одним аргументом.Поведение этого вызова undefined .Он может спокойно игнорировать посторонние аргументы - или он может повредить стек и привести к ужасной смерти вашей программы.(Последнее маловероятно; по историческим причинам большинство соглашений о вызовах C допускают такие ошибки.)
Если вы хотите, чтобы ваша функция printOut () не имела параметров и , вам нужен компиляторчтобы жаловаться, если вы называете это неправильно, определите это как:
void printOut(void)
{
...
}
Это единственный и единственный правильный способ написать это в C.
Конечно, если вы просто внесете это изменение ввашей программы, а затем добавьте вызов к printOut()
в main()
, у вас будет бесконечный рекурсивный цикл в ваших руках.Вы, вероятно, хотите, чтобы printOUt()
принял аргумент int
:
void printOut(int n)
{
...
}
Как это происходит, C ++ имеет другие правила.C ++ был получен из C, но с меньшей заботой о обратной совместимости.Когда Страуструп добавил прототипы в C ++, он вообще отбросил объявления старого стиля.Поскольку не было необходимости в специальном регистре void
для функций без параметров, void printOut()
в C ++ явно говорит, что printOut
не имеет параметров, и вызов с аргументами является ошибкой.C ++ также разрешает void printOut(void)
для совместимости с C, но это, вероятно, используется не очень часто (редко полезно писать код, который является допустимым C и допустимым C ++.) C и C ++ - два разных языка;Вы должны следовать правилам для любого языка, который вы используете.