C中int main()和int main(int argc,char* argv[])的區別?


有一個點大家都搞錯了。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
}

// 當然 C++ 就不一樣了


我從另外個角度為題主說明一下吧:

main是一個cdecl調用,

crt調用main的時候是:

push envp

push argv

push argc

call main

add 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]這麼訪問為什麼可以這麼寫?

TAG:編程 | C編程語言 | 編譯 |