網站首頁 編程語言 正文
一、main 函數的概念
- C語言中 main 函數稱之為主函數
- 一個C程序是從 main 函數開始執行的
二、main 函數的本質
- main 函數是操作系統調用的函數
- 操作系統總是將 main 函數作為應用程序的開始
- 操作系統將 main 函數的返回值作為程序的退出狀態
下面看一下 main 函數的返回值:
A.c:
#include <stdio.h> int main() { printf("I'm A!\n"); return 0; }
B.c:
#include <stdio.h> int main() { printf("I'm B!\n"); return 99; }
在 windows 下通過 VS012 命令行編譯代碼,如果對命令行編譯不熟悉,請看《命令行》,否則跳過該部分
以B.c 為例,編譯后通過 echo %ERRORLEVEL%
命令后,看到返回值為 99
下面再來進行一個實驗,先將 A 進行編譯,然后輸入 B.exe && A.exe,發現只打印出 I'm B!,因為 B.exe運行結束后操作系統返回了 99,99 在操作系統看來 B.exe 沒有正常運行退出,所以操作系統就不會運行 A.exe。
如果輸入 A.exe && B.exe,結果如下,這是因為 A.exe 運行結束后正常返回 0 給操作系統,所以就會往下執行 B.exe
命令行
以下面的代碼為例
test.h:
#ifndef _TEST_H_ #define _TEST_H_ #include <stdio.h> class Test { public: Test(const char* s) { printf("%s\n", s); } }; #endif
test.cpp:
#include "test.h" Test t4("t4"); int main() { Test t5("t5"); }
t1.cpp:
#include "test.h" Test t1("t1");
t2.cpp:
#include "test.h" Test t2("t2");
t3.cpp:
#include "test.h" Test t3("t3");
第一步,打開 VS2012,選擇 工具 -> Visual Studio 命令提示
第二步,實用 cd/d 進入需要編譯的文件夾。(注意換盤符需要輸入/d)
我想要編譯的文件在C:\Users\HuZeQiu\Desktop\demo 文件夾里。
輸入cd/d C:\Users\HuZeQiu\Desktop\demo,按下回車鍵,如下,就轉到了目的文件夾
第三步,輸入 cltest.cpp t2.cpp t1.cpp t3.cpp -otest.exe 編譯程序。(cl 命令是用來編譯程序)按下回車鍵后開始編譯,生成 test.exe 可執行文件,如下:
第四步,運行 test.exe,直接輸入 test.exe 即可,就可以看到運行結果
編譯后的文件夾如下:
三、main 函數的參數
程序執行時可以向 main 函數傳遞參數
gcc 編譯器的常見用法:
下面看一個 main 函數的參數示例:
#include <stdio.h> int main(int argc, char* argv[], char* env[]) { int i = 0; printf("============== Begin argv ==============\n"); for(i=0; i<argc; i++) { printf("%s\n", argv[i]); } printf("============== End argv ==============\n"); printf("\n"); printf("\n"); printf("\n"); printf("============== Begin env ==============\n"); for(i=0; env[i]!=NULL; i++) { printf("%s\n", env[i]); } printf("============== End env ==============\n"); return 0; }
輸出結果如下:
delphi@delphi-vm:~$ gcc test.c
delphi@delphi-vm:~$ ./a.out a.c b.c c.c ============== Begin argv ============== ./a.out a.c b.c c.c ============== End argv ==============
============== Begin env ==============
ORBIT_SOCKETDIR=/tmp/orbit-delphi SSH_AGENT_PID=1781 TERM=xterm SHELL=/bin/bash XDG_SESSION_COOKIE=6c560f89cd4609726ff940b800000007-1648713669.66817-1997070498 WINDOWID=71303204 QTDIR=/usr/local/Trolltech GNOME_KEYRING_CONTROL=/tmp/keyring-ZV2hRj GTK_MODULES=canberra-gtk-module USER=delphi LD_LIBRARY_PATH=/usr/local/Trolltech/Qt-4.7.4/lib:/usr/local/Trolltech/qtcreator-2.4.1/lib: LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arj=01;31:*.taz=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lz=01;31:*.xz=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.rar=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.axv=01;35:*.anx=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=00;36:*.au=00;36:*.flac=00;36:*.mid=00;36:*.midi=00;36:*.mka=00;36:*.mp3=00;36:*.mpc=00;36:*.ogg=00;36:*.ra=00;36:*.wav=00;36:*.axa=00;36:*.oga=00;36:*.spx=00;36:*.xspf=00;36: SSH_AUTH_SOCK=/tmp/keyring-ZV2hRj/ssh DEFAULTS_PATH=/usr/share/gconf/gnome.default.path SESSION_MANAGER=local/delphi-vm:@/tmp/.ICE-unix/1750,unix/delphi-vm:/tmp/.ICE-unix/1750 USERNAME=delphi XDG_CONFIG_DIRS=/etc/xdg/xdg-gnome:/etc/xdg DESKTOP_SESSION=gnome PATH=/usr/local/Trolltech/Qt-4.7.4/bin:/usr/local/Trolltech/qtcreator-2.4.1/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games QT_IM_MODULE=xim PWD=/home/delphi XMODIFIERS=@im=ibus GDM_KEYBOARD_LAYOUT=cn LANG=zh_CN.utf8 GNOME_KEYRING_PID=1731 MANDATORY_PATH=/usr/share/gconf/gnome.mandatory.path GDM_LANG=zh_CN.utf8 GDMSESSION=gnome SHLVL=1 HOME=/home/delphi LANGUAGE=zh_CN:zh GNOME_DESKTOP_SESSION_ID=this-is-deprecated LOGNAME=delphi XDG_DATA_DIRS=/usr/share/gnome:/usr/local/share/:/usr/share/ DBUS_SESSION_BUS_ADDRESS=unix:abstract=/tmp/dbus-k3N1W1OvOx,guid=5f504019e47302c3a7df0e2000000017 LESSOPEN=| /usr/bin/lesspipe %s WINDOWPATH=7 DISPLAY=:0.0 GTK_IM_MODULE=ibus LESSCLOSE=/usr/bin/lesspipe %s %s XAUTHORITY=/var/run/gdm/auth-for-delphi-omqXhW/database COLORTERM=gnome-terminal _=./a.out ============== End env ============== ?
四、main 函數一定是程序執行的第一個函數嗎
下面看一個示例:
#include <stdio.h> #ifndef __GNUC__ #define __attribute__(x) #endif __attribute__((constructor)) void before_main() { printf("%s\n",__FUNCTION__); } __attribute__((destructor)) void after_main() { printf("%s\n",__FUNCTION__); } int main() { printf("%s\n",__FUNCTION__); return 0; }
輸出結果如下:
constructor 告訴編譯器在 main 函數之前先調用,destructor 告訴編譯器在 main 函數之后調用。
如果在 windows 下的 VS2012 命令行窗口運行
#include <stdio.h> #ifndef __GNUC__ #define __attribute__(x) #endif __attribute__((constructor)) void before_main() { printf("%s\n", "before_main"); } __attribute__((destructor)) void after_main() { printf("%s\n", "after_main"); } int main() { printf("%s\n", "main"); return 0; }
輸出結果如下:
所以再來看這個問題:main 函數一定是程序執行的第一個函數嗎?
回答如下:不一定。假設使用 gcc 編譯器中的屬性關鍵字,就可以指定 main 函數之前可以執行一個函數,在 main 函數之后執行一個函數;對于沒有擴展屬性關鍵字的編譯器而言,main 函數一定是第一個函數。
五、小結
- 一個 C 程序是從 main 函數開始執行的
- main 函數是操作系統調用的函數
- main 函數有參數和返回值
- 現代編譯器支持在 main 函數前調用其它函數
原文鏈接:https://blog.csdn.net/weixin_43129713/article/details/123873052
相關推薦
- 2024-01-29 Linux信號量以及基于環形隊列的生產者消費者模型
- 2022-09-28 LyScript實現對內存堆棧掃描的方法詳解_python
- 2022-06-13 matplotlib繪制甘特圖的萬能模板案例_python
- 2022-12-29 基于R語言時間序列的平穩時間序列模型預測圖文詳解_R語言
- 2022-05-10 springMVC 文件上傳和下載
- 2022-05-12 uni-app混合原生安卓開發
- 2023-02-23 GoLang的sync.WaitGroup與sync.Once簡單使用講解_Golang
- 2022-04-15 使用python測試prometheus的實現_python
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支