C中int main()和int main(int argc,char* argv[])的區別?
01-06
有一個點大家都搞錯了。C語言里不接受參數的函數必須寫成 foo(void)。寫成 foo() 表示這個函數可以接受任意數量參數,相當於 foo(...)。
int a() {
return 1;
}
int b(void) {
return 1;
}
int main() {
a(10); //OK
b(10); //Error: Too many arguments
}
我從另外個角度為題主說明一下吧:main是一個cdecl調用,
crt調用main的時候是:
push envppush argvpush argccall mainadd esp,0x0c
這樣的話,實際上三個參數(argc argv envp)已經到堆棧上面了,最後的add esp也會修正堆棧,所以你拿不拿這三個參數都可以,這就是為什麼你在括弧裡面填參數也沒問題,不填也沒問題的原因。msvc crt里調用main函數的時候其實用了三個參數,你用main()就沒用參數,用main(int argc)就接收一個,以此類推,至於參數的作用,其它回答里已經說了
不請自來。在命令行運行程序時,經常會在要運行的程序後提供若干命令參數。
例如Linux中的ls -r 中的r就是附加命令參數。
argc的意思是調用程序時命令行提供的參數數量,argv字元數組提供參數表。這樣在編寫的時候程序員就可以通過這兩個變數來設計程序功能。比如當argv數組裡的某個元素是某字元時轉向什麼操作等。而如果參數為空就不通過參數表設計程序功能。int main(int argc, char* argv[]) 可使用命令行參數。
首先有一點原因是cdecl的調用者清理棧,這是main這樣玩的「物質基礎」,你看java的main就不能這麼玩
然後呢調用者(通常是libc,glibc,或者stdlib(或者clr?不過這樣就不是彙編而是cil了))永遠是按照main(argc,argv,env)的方式調用的,而linker只看main的符號(main或者__main),main的特殊性就在沒有命名修飾上了。
所以效果就是main就不知道libc給它傳了三個參數依然愉快得跑Linker需要一個用作entry point的函數符號;cdecl name mangling中不會包括函數參數的相關信息,因此兩種寫法在Linker看起來是一樣的。
推薦閱讀:
※新手使用c primer plus中文第五版學習c語言,windows下推薦用什麼編譯器?
※如何看c primer plus這本書?
※Qt C++ 如何實現自我反射?
※C++里,1[p]這麼訪問為什麼可以這麼寫?