Здесь есть две или три разные маленькие загадки. Не знаю, какой из них вам интересен, поэтому я думаю, что я отвечу на все три.
Как вам удалось объявить int main(i)
без типа для i
?
Как вам удалось объявить main
принятием одного параметра, а не обычного двух?
Откуда пришло значение 1с того момента, когда вы его запустили?
Ответы:
(1) Давным-давно, довольно давно, сейчас, что в значительной степени считается рассветом(или, по крайней мере, утром) из C, синтаксис определения функции был другим. Вы не говорили что-то вроде
int main(int argc, char *argv[])
{
...
}
Вместо этого вы говорили
int main(argc, argv)
int argc;
char *argv[];
{
...
}
И это было тогда, когда "неявное int
" было также всей яростью. Так что если вы только что написали
int main(argc, argv)
char *argv[];
{
...
}
, компилятор сказал: «Хорошо, есть параметр argv
, и это char **
, и есть параметр argc
, и это ... о, вы неНе скажу, так что я просто спокойно предположу int
. "
И поскольку C всегда был довольно большим по обратной совместимости, многие компиляторы все еще принимают старый синтаксис сегодня, даже если он официально устарелна некоторое время.
(2) Кроме того, в вашем случае вы полностью остановили часть argv
. Предполагается, что main
имеет два аргумента, поэтому система вызывает его при запуске вашей программы, но вы объявили его как принимающий. Так почему же это работает?
Строго говоря, поведение не определено, когда функция вызывается с другим числом аргументов, чем она ожидает, но с этим часто можно сойти, особенно в случаечто было передано больше аргументов, чем ожидалось. Таким образом, хотя система передала второй аргумент argv
, которого ваша программа не ожидала, дополнительный аргумент был просто незаметно отброшен.
(3) А потом, откуда взялся 1? Ну, это связано с тем, что на самом деле означают обычные argc
и argv
аргументы main
. Определение C main
основано на вызове командной строки. Обычно люди вводят такие вещи, как
programname somefilename someotherargument
, а затем нажимают RETURN. Это вызывает программу с именем programname
с двумя аргументами командной строки somefilename
и someotherargument
. Так как же они передаются в main
?
Ну, argc
- это подсчет их количества, а argv
- массив (v для "вектора")сами аргументные строки. И список аргументов всегда включает само название программы. Так что если вы вызываете
programname somefilename someotherargument
, то argc
входит как 3, а argv
входит как массив
{ "programname", "somefilename", "someotherargument", NULL }
Но если вы вызываете что-то без аргументов, тогда argc
все еще входит как 1. Так вот откуда пришла 1, которую вы видели.