文章目录
(一)main函数返回给谁?
1.函数为什么需要返回值
1.== 函数在设计的时候设计了参数和返回值,参数是函数的输入,返回值是函数的输出==。
2. 因为函数需要对外输出数据(实际上是函数运行的一些结果值)因此需要返回值
3. 形式上来说,函数被另一个函数所调用,返回值作为函数式的值返回给调用这个函数的地方
4. 总结:函数的返回值就是给调用它的人返回一个值
2.main函数被谁调用?
- main函数是特殊的,首先这个名字是特殊的。因为C语言规定了main函数是整个程序的入口。其他的函数只有直接或间接被main函数所调用才能被执行,如果没有被main直接/间接调用则这个函数在整个程序中无用。
- main函数从某种角度来讲代表了我当前这个程序,或者说代表了整个程序。main函数的开始意味着整个程序开始执行,main函数的结束返回意味着整个程序的结束。
- 谁执行了这个程序,谁就调用了main。
- 谁执行了程序?或者说程序有哪几种被调用执行的方法?
- 我们接着往下看
3.linux下一个新程序执行的本质
- 表面来看,linux中在命令行中去./xx执行一个可执行程序
- 我们还可以通过shell脚本来调用执行一个程序
- 我们还可以在程序中去调用执行一个程序(fork exec)
- 总结:我们有多种方法都可以执行一个程序,但是本质上是相同的。 linux中一个新程序的执行本质上是一个进程的创建、加载、运行、消亡。linux中执行一个程序其实就是创建一个新进程然后把这个程序丢进这个进程中去执行直到结束。新进程是被谁开启?在linux中进程都是被它的父进程fork出来的。
- 分析:命令行本身就是一个进程,在命令行底下去./xx执行一个程序,其实这个新程序是作为命令行进程的一个子进程去执行的。
- 总之一句话:一个程序被它的父进程所调用。
- 结论:main函数返回给调用这个函数的父进程。父进程要这个返回值干嘛?父进程调用子进程来执行一个任务,然后字进程执行完后通过main函数的返回值返回给父进程一个答复。这个答复一般是表示子进程的任务执行结果完成了还是错误了。(0表示执行成功,负数表示失败)
4.实践验证获取main的返回值
- 用shell脚本执行程序可以获取程序的返回值并且打印出来
- linux shell中用
$?
这个符号来存储和表示上一个程序执行结果。echo打印$?
的内容
(二)argc、argv与main函数的传参
1.谁给main函数传参
- 调用main函数所在的程序的它的父进程给main函数传参,并且接收main的返回值。
2.为什么需要给main函数传参?
- 首先,main函数不传参是可以的,也就是说父进程调用子程序并且给子程序传参不是必须的。 int main(void)这种形式就表示我们认为不必要给main传参。
- 有时候我们希望程序有一种灵活性,所以选择在执行程序时通过传参来控制程序中的运行,达到不需要重新编译程序就可以改变程序运行结果的效果。
3.表面上:给main传参是怎样实现的?
- 给main传参通过argc和argv这两个C语言预订的参数来实现
- argc是int类型,表示运行程序的时候给main函数传递了几个参数;argv是一个字符串数组,这个数组用来存储多个字符串,每个字符串就是我们给main函数传的一个参数。argv[0]就是我们给main函数的第一个传参,argv[1]就是传给main的第二个参数····
4.本质上:给main传参是怎样实现的?
- 程序调用有各种方法但是本质上都是父进程fork一个子进程,然后字进程和一个程序绑定起来去执行(exec函数族),我们在exec的时候可以给他同时传参。
- 程序调用时可以被传参(也就是main的传参)是操作系统层面的支持完成的。
5.给main传参要注意什么
- main函数传参都是通过字符串传进去的。
- 程序被调用时传参,各个参数之间是通过空格来间隔的。
- 在程序内部如果要使用argv,那么一定要先检验argc。
- 程序执行
./a.out
也算是一个参数
6.实例
#include <stdio.h>
int main (int argc, char **argv)
{
int i = 0;
int add0 = 0, add1 = 0;
printf("main传入了%d个参数.\n", argc);
for(i = 0; i < argc; i++)
{
printf("main传入的第%d个参数是%s.\n", (i + 1) , *(argv + i));
}
if (argc != 4)
{
printf("we need 4 param.\n");
return -1;
}
return 0;
}