main()函数是c程序入口的入口点怎么理解

C语言,如何在一个函数内部,获取这个函数入口点的地址? - 开源中国社区
当前访客身份:游客 [
当前位置:
#include #include void show(void* p) { printf("%p\n",p); } int main() { show(&show); show(show); return 0; } Output: 1 2 0xx8048480
共有4个答案
<span class="a_vote_num" id="a_vote_num_
这个并非内部获取,如果要内部获取,就应该不传任何参数
<span class="a_vote_num" id="a_vote_num_
<span class="a_vote_num" id="a_vote_num_
#include #include void show() { printf("%p\n",show); } int main() { show(); return 0; }
<span class="a_vote_num" id="a_vote_num_
更多开发者职位上
有什么技术问题吗?
乌合之众的其它问题
类似的话题wpf项目程序的入口点函数是什么呀?我找不到Main()呀?-c/c++-电脑编程网wpf项目程序的入口点函数是什么呀?我找不到Main()呀?作者:zwth001 和相关&&wpf项目程序的入口点函数是什么呀?我找不到Main()呀?-----------------------------------------------wpf项目很有意思,学着做一个,可是我竟然找不到入口点函数,在哪里呢?难道不是 Main()了吗?我如何能找到它的入口点呢?------回答---------------其他回答(10分)---------Application的派生的类中(当然我们也可以放到别的类中)。public class myApp:Application&
[STAThread]&
public static void Main()&
Application app = new Application();&
MainWindow window = new MainWindow();&
window.Show();&
app.Run();&
}}& /NineFlowers/archive//1292886.html------其他回答(10分)---------public partial class App : System.Windows.Application {&
[System.STAThreadAttribute()]&
public static void Main() {&
SysClient.App app = new SysClient.App();&
app.InitializeComponent();&
app.Run();&
}WPF应用程序------回答---------------其他回答(10分)---------Application的派生的类中(当然我们也可以放到别的类中)。public class myApp:Application &
[STAThread] &
public static void Main() &
Application app = new Application(); &
MainWindow window = new MainWindow(); &
window.Show(); &
app.Run(); &
}}& /NineFlowers/archive//1292886.html------其他回答(10分)---------public partial class App : System.Windows.Application { &
[System.STAThreadAttribute()] &
public static void Main() { &
SysClient.App app = new SysClient.App(); &
app.InitializeComponent(); &
app.Run(); &
}WPF应用程序相关资料:|||||||wpf项目程序的入口点函数是什么呀?我找不到Main()呀?来源网络,如有侵权请告知,即处理!编程Tags:                &                    深入理解 C 语言的函数调用过程 - 文章 - 伯乐在线
& 深入理解 C 语言的函数调用过程
本文主要从进程栈空间的层面复习一下C语言中函数调用的具体过程,以加深对一些基础知识的理解。
先看一个最简单的程序:
主函数main里定义了4个局部变量,然后调用同文件里的foo1()函数。4个局部变量毫无疑问都在进程的栈空间上,当进程运行起来后我们逐步了解一下main函数里是如何基于栈实现了对foo1()的调用过程,而foo1()又是怎么返回到main函数里的。为了便于观察的粒度更细致一些,我们对test.c生成的汇编代码进行调试。如下:
.file "test.c"
.globl foo1
.type foo1
pushl %ebp
movl %esp, %ebp
subl $16, %esp
movl 12(%ebp), %eax
movl 8(%ebp), %edx
leal (%edx,%eax), %eax
addl 16(%ebp), %eax
movl %eax, -4(%ebp)
movl -4(%ebp), %eax
.size foo1, .-foo1
.section .rodata
.string "result=%d\n"
.globl main
.type main
pushl %ebp
movl %esp, %ebp
andl $-16, %esp
subl $32, %esp
movl $11, 16(%esp)
movl $22, 20(%esp)
movl $33, 24(%esp)
movl 24(%esp), %eax
movl %eax, 8(%esp)
movl 20(%esp), %eax
movl %eax, 4(%esp)
movl 16(%esp), %eax
movl %eax, (%esp)
movl %eax, 28(%esp)
movl $.LC0, %eax
movl 28(%esp), %edx
movl %edx, 4(%esp)
movl %eax, (%esp)
call printf
movl $0, %eax
.size main, .-main
.ident "GCC: (GNU) 4.4.4
(Red Hat 4.4.4-13)"
.section .note.GNU-stack,"",@progbits
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
.file "test.c"&&&&&&&&.text.globl foo1&&&&&&&&.type foo1foo1:&&&&&&&&pushl %ebp&&&&&&&&movl %esp, %ebp&&&&&&&&subl $16, %esp&&&&&&&&movl 12(%ebp), %eax&&&&&&&&movl 8(%ebp), %edx&&&&&&&&leal (%edx,%eax), %eax&&&&&&&&addl 16(%ebp), %eax&&&&&&&&movl %eax, -4(%ebp)&&&&&&&&movl -4(%ebp), %eax&&&&&&&&leave&&&&&&&&ret&&&&&&&&.size foo1, .-foo1&&&&&&&&.section .rodata.LC0:&&&&&&&&.string "result=%d\n"&&&&&&&&.text.globl main&&&&&&&&.type mainmain:&&&&&&&&pushl %ebp&&&&&&&&movl %esp, %ebp&&&&&&&&andl $-16, %esp&&&&&&&&subl $32, %esp&&&&&&&&movl $11, 16(%esp)&&&&&&&&movl $22, 20(%esp)&&&&&&&&movl $33, 24(%esp)&&&&&&&&movl 24(%esp), %eax&&&&&&&&movl %eax, 8(%esp)&&&&&&&&movl 20(%esp), %eax&&&&&&&&movl %eax, 4(%esp)&&&&&&&&movl 16(%esp), %eax&&&&&&&&movl %eax, (%esp)&&&&&&&&call foo1&&&&&&&&movl %eax, 28(%esp)&&&&&&&&movl $.LC0, %eax&&&&&&&&movl 28(%esp), %edx&&&&&&&&movl %edx, 4(%esp)&&&&&&&&movl %eax, (%esp)&&&&&&&&call printf&&&&&&&&movl $0, %eax&&&&&&&&leave&&&&&&&&ret&&&&&&&&.size main, .-main&&&&&&&&.ident "GCC: (GNU) 4.4.4
(Red Hat 4.4.4-13)"&&&&&&&&.section .note.GNU-stack,"",@progbits
上面的汇编源代码和最终生成的可执行程序主体结构上已经非常类似了:
1]# gcc -g -o test test.s
1]# objdump -D test & testbin
1]# vi testbin
//… 省略部分不相关代码
$0x10,%esp
0xc(%ebp),%eax
0x8(%ebp),%edx
(%edx,%eax,1),%eax
0x10(%ebp),%eax
%eax,-0x4(%ebp)
-0x4(%ebp),%eax
$0xfffffff0,%esp
$0x20,%esp
c7 44 24 10 0b 00 00
$0xb,0x10(%esp)
c7 44 24 14 16 00 00
$0x16,0x14(%esp)
c7 44 24 18 21 00 00
$0x21,0x18(%esp)
8b 44 24 18
0x18(%esp),%eax
89 44 24 08
%eax,0x8(%esp)
8b 44 24 14
0x14(%esp),%eax
89 44 24 04
%eax,0x4(%esp)
8b 44 24 10
0x10(%esp),%eax
%eax,(%esp)
e8 a9 ff ff ff
89 44 24 1c
%eax,0x1c(%esp)
b8 04 85 04 08
$0x8048504,%eax
8b 54 24 1c
0x1c(%esp),%edx
89 54 24 04
%edx,0x4(%esp)
%eax,(%esp)
e8 c0 fe ff ff
b8 00 00 00 00
//… 省略部分不相关代码
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
[root&&1]# gcc -g -o test test.s[root&&1]# objdump -D test & testbin[root&&1]# vi testbin //… 省略部分不相关代码80483c0:&&&&&& ff d0&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& call&& *%eax 80483c2:&&&&&& c9&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& leave 80483c3:&&&&&& c3&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& ret
: 80483c4:&&&&&& 55&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&push&& %ebp 80483c5:&&&&&& 89 e5&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& mov&&&&%esp,%ebp 80483c7:&&&&&& 83 ec 10&&&&&&&&&&&&&&&&&&&&&&&&&&sub&&&&$0x10,%esp 80483ca:&&&&&& 8b 45 0c&&&&&&&&&&&&&&&&&&&&&&&&&&mov&&&&0xc(%ebp),%eax 80483cd:&&&&&& 8b 55 08&&&&&&&&&&&&&&&&&&&&&&&& mov&&&&0x8(%ebp),%edx 80483d0:&&&&&& 8d 04 02&&&&&&&&&&&&&&&&&&&&&&&& lea&&&&(%edx,%eax,1),%eax 80483d3:&&&&&& 03 45 10&&&&&&&&&&&&&&&&&&&&&&&& add&&&&0x10(%ebp),%eax 80483d6:&&&&&& 89 45 fc&&&&&&&&&&&&&&&&&&&&&&&&&&mov&&&&%eax,-0x4(%ebp) 80483d9:&&&&&& 8b 45 fc&&&&&&&&&&&&&&&&&&&&&&&&&&mov&&&&-0x4(%ebp),%eax 80483dc:&&&&&& c9&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& leave 80483dd:&&&&&& c3&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& ret 080483de: 80483de:&&&&&& 55&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& push&& %ebp 80483df:&&&&&& 89 e5&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& mov&&&&%esp,%ebp 80483e1:&&&&&& 83 e4 f0&&&&&&&&&&&&&&&&&&&&&&&&&&&&and&&&&$0xfffffff0,%esp 80483e4:&&&&&& 83 ec 20&&&&&&&&&&&&&&&&&&&&&&&&&& sub&&&&$0x20,%esp 80483e7:&&&&&& c7 44 24 10 0b 00 00&&&&&& movl&& $0xb,0x10(%esp) 80483ee:&&&&&& 00 80483ef:&&&&&& c7 44 24 14 16 00 00&&&&&&&&movl&& $0x16,0x14(%esp) 80483f6:&&&&&& 00 80483f7:&&&&&& c7 44 24 18 21 00 00&&&&&&&&movl&& $0x21,0x18(%esp) 80483fe:&&&&&& 00 80483ff:&&&&&& 8b 44 24 18&&&&&&&&&&&&&&&&&&&&&&mov&&&&0x18(%esp),%eax 8048403:&&&&&& 89 44 24 08&&&&&&&&&&&&&&&&&&&&mov&&&&%eax,0x8(%esp) 8048407:&&&&&& 8b 44 24 14&&&&&&&&&&&&&&&&&&&&mov&&&&0x14(%esp),%eax 804840b:&&&&&& 89 44 24 04&&&&&&&&&&&&&&&&&&&&mov&&&&%eax,0x4(%esp) 804840f:&&&&&& 8b 44 24 10&&&&&&&&&&&&&&&&&&&& mov&&&&0x10(%esp),%eax 8048413:&&&&&& 89 04 24&&&&&&&&&&&&&&&&&&&&&&&& mov&&&&%eax,(%esp) 8048416:&&&&&& e8 a9 ff ff ff&&&&&&&&&&&&&&&&&&&& call&& 80483c4 804841b:&&&&&& 89 44 24 1c&&&&&&&&&&&&&&&&&&&& mov&&&&%eax,0x1c(%esp) 804841f:&&&&&& b8 04 85 04 08&&&&&&&&&&&&&&&& mov&&&&$0x8048504,%eax 8048424:&&&&&& 8b 54 24 1c&&&&&&&&&&&&&&&&&&&& mov&&&&0x1c(%esp),%edx 8048428:&&&&&& 89 54 24 04&&&&&&&&&&&&&&&&&&&& mov&&&&%edx,0x4(%esp) 804842c:&&&&&& 89 04 24&&&&&&&&&&&&&&&&&&&&&&&& mov&&&&%eax,(%esp) 804842f:&&&&&& e8 c0 fe ff ff&&&&&&&&&&&&&&&&&&&& call&& 80482f4 8048434:&&&&&& b8 00 00 00 00&&&&&&&&&&&&&&mov&&&&$0x0,%eax 8048439:&&&&&& c9&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&leave 804843a:&&&&&& c3&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&ret 804843b:&&&&&& 90&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& nop 804843c:&&&&&& 90&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& nop //… 省略部分不相关代码
用GDB调试可执行程序test:
在main函数第一条指令执行前我们看一下进程test的栈空间布局。因为我们最终的可执行程序是通过glibc库启动的,在main的第一条指令运行前,其实还有很多故事的,这里就不展开了,以后有时间再细究,这里只要记住一点:main函数执行前,其进程空间的栈里已经有了相当多的数据。我的系统里此时栈顶指针esp的值是0xbffff63c,栈基址指针ebp的值0xbffff6b8,指令寄存器eip的值是0x80483de正好是下一条马上即将执行的指令,即main函数内的第一条指令“push %ebp”。那么此时,test进程的栈空间布局大致如下:
然后执行如下三条指令:
pushl %ebp
//将原来ebp的值0xbffff6b8如栈,esp自动增长4字节
movl %esp, %ebp
//用ebp保存当前时刻esp的值
andl $-16, %esp
//内存地址对其,可以忽略不计
pushl %ebp&&&&&&&& //将原来ebp的值0xbffff6b8如栈,esp自动增长4字节movl %esp, %ebp&&&&//用ebp保存当前时刻esp的值andl $-16, %esp&&&&//内存地址对其,可以忽略不计
行完上述三条指令后栈里的数据如上图所示,从0xbffff630到0xbffff638的8字节是为了实现地址对齐的填充数据。此时ebp的值0xbffff638,该地址处存放的是ebp原来的值0xbffff6b8。详细布局如下:
第28条指令“subl $32, %esp”是在栈上为函数里的本地局部变量预留空间,这里我们看到main主函数有4个int型的变量,理论上说预留16字节空间就可以了,但这里却预留了32字节。GCC编译器在生成汇编代码时,已经考虑到函数调用时其输入参数在栈上的空间预留的问题,这一点我们后面会看到。当第28条指令执行完后栈空间里的数据和布局如下:
然后main函数里的变量x,y,z的值放到栈上,就是接下来的三条指令:
movl $11, 16(%esp)
movl $22, 20(%esp)
movl $33, 24(%esp)
movl $11, 16(%esp)movl $22, 20(%esp)movl $33, 24(%esp)
这是三条寄存器间接寻址指令,将立即数11,22,33分别放到esp寄存器所指向的地址0xbffff610向高位分别偏移16、20、24个字节处的内存单元里,最后结果如下:
注意:这三条指令并没有改变esp寄存器的值。
接下来main函数里就要为了调用foo1函数而做准备了。由于mov指令的两个操作数不能都是内存地址,所以要将x,y和z的值传递给foo1函数,则必须借助通用寄存器来完成,这里我们看到eax承担了这样的任务:
movl 24(%esp), %eax
movl %eax, 8(%esp)
movl 20(%esp), %eax
movl %eax, 4(%esp)
movl 16(%esp), %eax
movl %eax, (%esp)
movl 24(%esp), %eaxmovl %eax, 8(%esp)movl 20(%esp), %eaxmovl %eax, 4(%esp)movl 16(%esp), %eaxmovl %eax, (%esp)
当foo1函数所需要的所有输入参数都已经按正确的顺序入栈后,紧接着就需要调用call指令来执行foo1函数的代码了。前面的博文说过,call指令执行时分两步:首先会将call指令的下一条指令(movl %eax, 28(%esp))的地址(0x0804841b)压入栈,然后跳转到函数foo1入口处开始执行。当第38条指令“call foo1”执行完后,栈空间布局如下:
call指令自动将下一条要执行的指令的地址0x0804841b压入栈,栈顶指针esp自动向低地址处“增长”4字节。所以,我们以前在C语言里所说的函数返回地址,应该理解为:当被调用函数执行完之后要返回到它的调用函数里下一条马上要执行的代码的地址。为了便于观察,我们把foo1函数最后生成指令再列出来:
.globl foo1
.type foo1
pushl %ebp
movl %esp, %ebp
subl $16, %esp
movl 12(%ebp), %eax
movl 8(%ebp), %edx
leal (%edx,%eax), %eax
addl 16(%ebp), %eax
movl %eax, -4(%ebp)
movl -4(%ebp), %eax
.size foo1, .-foo1
123456789101112131415
.globl foo1&&&&&&&&&& .type foo1 foo1:&&&&&&&&&& pushl %ebp&&&&&&&&&& movl %esp, %ebp&&&&&&&&&& subl $16, %esp&&&&&&&&&& movl 12(%ebp), %eax&&&&&&&&&&movl 8(%ebp), %edx&&&&&&&&&&leal (%edx,%eax), %eax&&&&&&&&&&addl 16(%ebp), %eax&&&&&&&& movl %eax, -4(%ebp)&&&&&&&&&&movl -4(%ebp), %eax&&&&&&&&&&leave&&&&&&&&&&ret&&&&&&&&&&.size foo1, .-foo1
进入到foo1函数里,开始执行该函数里的指令。当执行完第6、7、8条指令后,栈里的数据如下。这三条指令就是汇编层面函数的“序幕”,分别是保存ebp到栈,让ebp指向当前栈顶,然后为函数里的局部变量预留空间:
接下来第9和第10条指令,也并没有改变栈上的任何数据,而是将函数输入参数列表中的的x和y的值分别转载到eax和edx寄存器,和main函数刚开始时做的事情一样。此时eax=22、edx=11。然后用了一条leaf指令完成x和y的加法运算,并将运算结果存在eax里。第12条指令“addl 16(%ebp), %eax”将第三个输入参数p的值,这里是实参z的值为33,同样用寄存器间接寻址模式累加到eax里。此时eax=11+22+33=66就是我们最终要得计算结果。
因为我们foo1()函数的C代码中,最终计算结果是保存到foo1()里的局部变量x里,最后用return语句将x的值通过eax寄存器返回到mian函数里,所以我们看到接下来的第13、14条指令有些“多此一举”。这足以说明gcc人家还是相当严谨的,C源代码的函数里如果有给局部变量赋值的语句,生成汇编代码时确实会在栈上为本地变量预留的空间里的正确位置为其赋值。当然gcc还有不同级别的优化技术来提高程序的执行效率,这个不属于本文所讨论的东西。让我们继续,当第13、14条指令执行完后,栈布局如下:
将ebp-4的地址处0xbffff604(其实就是foo1()里的第一个局部参数x的地址)的值设置为66,然后再将该值复制到eax寄存器里,等会儿在main函数里就可以通过eax寄存器来获取最终的计算结果。当第15条指令leave执行完后,栈空间的数据和布局如下:
我们发现,虽然栈顶从0xbffff5f8移动到0xbffff60c了,但栈上的数据依然存在。也就是说,此时你通过esp-8依旧可以访问foo1函数里的局部变量x的值。当然,这也是说得通的,因为函数此时还没有返回。我们看栈布局可以知道当前的栈顶0xbffff60c处存放的是下一条即将执行的指令的地址,对照反汇编结果可以看到这正是main函数里的第18条指令(在整个汇编源文件test.s里的行号是39)“movl %eax, 28(%esp)”
leave指令其实完成了两个任务:
1、将栈上为函数预留的空间“收回”;
2、恢复ebp;
也就是说leave指令等价于下面两条指令,你将leave替换成它们编译运行,结果还是对的:
movl %ebp,%esp
movl %ebp,%esppopl %ebp
前面我们也说过,ret指令会自动到栈上去pop数据,相当于执行了“popl %eip”,会使esp增大4字节。所以当执行完第16条指令ret后,esp从0xbffff60c增长到0xbffff610处,栈空间结构如下:
现在已经从foo1里返回了,但是由于还没执行任何push操作,栈顶“上部”的数据依旧还是可以访问到了,即esp-12的值就是foo1里的局部变量x的值、esp-4的值就是函数的返回地址,当执行第39条指令“movl %eax,28(%esp)”后栈布局变成下面的样子:
第39条指令就相当于给main里的result变量赋值66,如上红线标注的地方。接下来main函数里要执行printf(&#8220;result=%d\n&#8221;,result)语句了,而printf又是C库的一个常用的输出函数,这里就又会像前面调用foo1那样,初始化栈,然后用“call printf的地址”来调用C函数。当40~43这4条指令执行完后,栈里的数据如下:
movl $.LC0, %eax
movl 28(%esp), %edx
movl %edx, 4(%esp)
movl %eax, (%esp)
movl $.LC0, %eaxmovl 28(%esp), %edxmovl %edx, 4(%esp)movl %eax, (%esp)
上图为了方便理解,将栈顶的0x替换了成字符串“result=%d\n”,但进程实际运行时此时栈顶esp的值是字符串所在的内存地址。当第44条指令执行完后,栈布局如下:
由于此时栈已经用来调用printf了,所以栈顶0xbffff610“以上”部分的空间里就找不到foo1的任何影子了。最后在main函数里,当第46、47条指令执行完后栈的布局分别是:
当main函数里的ret执行完,其实是返回到了C库里继续执行剩下的清理工作。
所以,最后关于C的函数调用,我们可以总结一下:
1、函数输入参数的入栈顺序是函数原型中形参从右至左的原则;
2、汇编语言里调用函数通常情况下都用call指令来完成;
3、汇编语言里的函数大部分情况下都符合以下的函数模板:
.globl fun_name
.type fun_name
pushl %ebp
movl %esp, %ebp
&函数主体代码&
.globl fun_name.type fun_namefun_name:&&&&&&&&pushl %ebp&&&&&&&&movl %esp, %ebp&&&&&&&&&函数主体代码& &&&&&&&&leave&&&&&&&&ret
如果我们有个函数原型:int funtest(int x,int y int z char* ptr),在汇编层面,当调用它时栈的布局结构一般是下面这个样子:
而有些资料上将ebp指向函数返回地址的地方,这是不对的。正常情况下应该是ebp指向old ebp才对,这样函数末尾的leave和ret指令才可以正常工作。
可能感兴趣的话题
讲解的很详细
关于伯乐在线博客
在这个信息爆炸的时代,人们已然被大量、快速并且简短的信息所包围。然而,我们相信:过多“快餐”式的阅读只会令人“虚胖”,缺乏实质的内涵。伯乐在线内容团队正试图以我们微薄的力量,把优秀的原创文章和译文分享给读者,为“快餐”添加一些“营养”元素。
新浪微博:
推荐微信号
(加好友请注明来意)
&#8211; 好的话题、有启发的回复、值得信赖的圈子
&#8211; 分享和发现有价值的内容与观点
&#8211; 为IT单身男女服务的征婚传播平台
&#8211; 优秀的工具资源导航
&#8211; 翻译传播优秀的外文文章
&#8211; 国内外的精选文章
&#8211; UI,网页,交互和用户体验
&#8211; 专注iOS技术分享
&#8211; 专注Android技术分享
&#8211; JavaScript, HTML5, CSS
&#8211; 专注Java技术分享
&#8211; 专注Python技术分享
& 2016 伯乐在线C语言的主函数是什么意思_c语言吧_百度贴吧
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&签到排名:今日本吧第个签到,本吧因你更精彩,明天继续来努力!
本吧签到人数:0成为超级会员,使用一键签到本月漏签0次!成为超级会员,赠送8张补签卡连续签到:天&&累计签到:天超级会员单次开通12个月以上,赠送连续签到卡3张
关注:503,197贴子:
C语言的主函数是什么意思收藏
#include&stdio.h& int main(){ printf (&hello word! . \n&); return 0; } int main()
主要起着什么作用?以上代码难道就是调取 printf
这个打印函数吗?
告别死工资:送150美金,可提取
我也是新手,刚看的这个,我觉得是的
主函数是入口函数 程序一定从主函数开始执行
程序必须从int main开始执行 不论把它放在哪里
main函数是执行程序的入口,
程序第一个运行的函数。
一个程序有一个而且只有一个主函数main().
计算机总要从一个地方开始执行你的程序吧就像你穿袜子,总得有个入口吧入口就是main函数这个函数由操作系统调用
     别看我,我只是凑够十五字的,不信你数。 
优势:1、152元/年起;2、住院+重疾+特殊门诊一险均保;3、保额高至300万…
我好像和你是同学
有没有q群,已经上了好多节课还是没学到什么
printf(& liti %d\n&,sum);
这句话的意思是什么?
printf 打印输出函数
(& liti %d\n&,sum); liti为用户主动输出文字,%d代表输出显示格式(十进制格式)显示小括号中的sum sum取代了%d
这样注释对不对?
但我还是不太明白,
怎么取代 %d 的
这个入口点函数不就是main函数的意思吗?
好比你给计算机发个窝窝头,计算机不知道从哪开始啃,你在窝窝头上画了个圈,计算机就知道了
主函数就是main函数,程序入口作用。
main()函数是程序的运行入口,为什么会是这样,估计是创造C语言的这个人故意所为
就是一个函数
入口函数是os在运行程序时开始运行的地方main是c语言标准所规定的主函数,但不一定是入口。linux是拿main函数当入口函数的,但windows不是,windows下main是被标准库调用的,标准库里包含入口函数
登录百度帐号推荐应用
为兴趣而生,贴吧更懂你。或

我要回帖

更多关于 c程序入口 的文章

 

随机推荐