38.main函数传参和void类型


38.1.计算机软件系统发展史
(1)人类社会最开始时人人都干活,这时候没有专业分工,所有人都直接做产生价值的工作,在当时是合适的,因为当时生产力低下,人口稀少;即可类比裸机程序,裸机程序代码量小,功能简单,所有代码都和直接目的有关,没有服务性代码。
(2)后来人口增加生产力提高,有部分人脱离了直接产生价值的体力劳动专职指挥(诞生了阶级),本质上来说是合理的,因为资源得到了更大限度的使用,优化了配置,提升了整体效率;当计算机技术发展,计算机性能和资源大量增加,此时写代码也要产生阶级进行分工,否则若所有代码都去参加直接性的工作,则整体系统效率不高,因为代码很难进行资源的优化配置。
(3)操作系统就是分出来的管理阶级,操作系统的代码本身并不直接产生价值,它的主要任务是管理所有资源,它主要为直接产生价值、直接劳动的那些程序(各种应用程序)提供服务,则操作系统既是管理者也是服务者。
(4)裸机程序即小公司,操作系统下即大型跨国公司,裸机程序即小国家,操作系统即大国家;如果我们要做某个产品,软件系统到底应该是裸机还是基于操作系统呢,本质上取决于产品本身的复杂度;只有极简单的功能、使用极简单的CPU(譬如单片机)的产品才会选择用裸机开发;一般的复杂性产品都会选择基于操作系统来开发。


38.2.C库函数和API函数
(1)操作系统负责管理和资源调配,应用程序负责具体的直接劳动,它们之间的接口即API函数;当应用程序需要使用系统资源(譬如内存/CPU/硬件操作)时就通过API向操作系统发出申请,然后操作系统响应申请帮助应用程序执行功能。
(2)单纯的API只是提供了极简单没有任何封装的服务函数,这些API函数应用程序是可以使用的,但是不太好用,应用程序为了好用,就对该API进行了二次封装,把它变得好用一些,于是就成了C库函数。
(3)有时相同的功能使用相应的库函数和API都可以完成,譬如读写文件,API的接口是open/write/read/close,库函数的接口是fopen/fwrite/fread/fclose,fopen本质上是使用open实现的,只是进行了封装,此处封装的目的是添加了缓冲机制。
(4)不同操作系统API是不同的,但是都能完成所有的任务,只是完成任务所调用的API不同;库函数在不同操作系统下也不同,但是相似性要更高一些;因为人下意识想要屏蔽不同操作系统的差异,因此在封装API成库函数的时候,尽量使用了同一套接口,所以封装出来的库函数挺像的,但是还是有差异;则在某个操作系统上写的应用程序不可能直接在不同的操作系统上面编译运行;则产生了跨操作系统可移植平台,譬如QT/Java语言。
(5)有了操作系统后,我们做某个产品可分成2部分,一部分人负责做操作系统(开发驱动);一部分人负责用操作系统实现具体功能(开发应用);实际上上层应用层的功能进一步复杂化后又分了好多层。


38.3.main函数返回给谁
(1)函数为什么需要返回值;函数在设计的时候设计了参数和返回值,参数是函数的输入,返回值是函数的输出;因为函数需要对外输出数据则需要返回值;形式上来说,函数被另外的函数所调用,返回值作为函数式的值返回给调用该函数的地方;函数的返回值就是给调用它的人返回某个值。
(2)main函数被谁调用;main函数是特殊的,首先名字是特殊的,因为C语言规定了main函数是整个程序的入口,其它的函数只有直接或间接被main函数所调用才能被执行,如果没有被main直接/间接调用则该函数在整个程序中无用;main函数从某种角度来讲代表了整个程序,main函数的开始意味着整个程序开始执行,main函数的结束返回意味着整个程序的结束;谁执行了该程序,谁就调用了main函数。
(3)linux下新程序执行的本质;表面来看linux中在命令行中去./xx执行某个可执行程序;我们可以通过shell脚本来调用执行某个程序;我们还可以在程序中去调用执行某个程序(fork/exec)。
(4)linux中某个新程序的执行本质上是进程的创建+加载+运行+消亡;linux中执行某个程序其实就是创建1个新进程然后把该程序丢进该进程中去执行直到结束;新进程是被谁开启,在linux中进程都是被它的父进程fork出来的;
(5)main函数返回给调用该函数的父进程,父进程调用子进程来执行某个任务,然后子进程执行完后通过main函数的返回值返回给父进程答复,该答复是表示子进程的任务执行结果成功还是错误,0表示执行成功,负数表示失败。
(6)获取main的返回值;用shell脚本执行程序可以获取程序的返回值并且打印出来;使用$?该符号来存储和表示上一个程序执行结果(./a.out; ehco &?)。


38.4.argc及argv与main函数传参
(1)谁给main函数传参,调用main函数所在的程序的父进程给main函数传参并且接收main的返回值;为什么需要给main函数传参,main函数不传参是可以的,即父进程调用子程序并且给子程序传参不是必须的,int_main(void)该种形式表示我们认为不必要给main传参;有时候我们希望选择在执行程序时通过传参来控制程序中的运行,达到不需要重新编译程序就可以改变程序运行结果的效果。
(2)表面上实现给main传参,给main传参通过argc和argv这两个C语言预订的参数来实现;argc是int类型表示运行程序的时候给main函数传递了几个参数;argv是字符串数组,该数组用来存储多个字符串,每个字符串就是我们给main函数传的1个参数;argv[0]就是我们给main函数的第1个传参,argv[1]就是传给main的第2个参数。
(3)本质上实现给main传参,程序调用有各种方法但本质上都是父进程fork子进程,然后子进程和1个程序绑定起来去执行(exec函数族),我们在exec的时候可以给它传参;程序调用时可以被传参(即main的传参)是操作系统层面的支持完成的。
(4)main函数传参都是通过字符串传进去的;程序被调用时传参,各个参数之间是通过空格来间隔的;在程序内部如果要使用argv则一定要先检验argc。


38.5.void类型的本质
(1)C语言属强类型语言,编程语言分为强类型语言+弱类型语言;强类型语言中所有变量都有自己固定的类型,该类型有固定的内存占用空间,有固定的解析方法;弱类型语言中没有类型的概念,所有变量全都是相同的类型(一般是字符串),程序在使用时再根据需要来处理变量。
(2)C语言是典型的强类型语言,C语言中所有的变量都有明确的类型,因为C语言中的每个变量都要对应内存中的某段内存,则编译器需要通过该变量的类型来确定该变量占用内存的字节数和该段内存的解析方法。
(3)数据类型的本质决定变量的内存占用数和内存的解析方法,则c语言中变量必须有确定的数据类型,若某个变量没有确定的类型(即无类型)则会导致编译器无法给该变量分配内存,也无法解析该变量对应的内存。
(4)C语言中可以有没有类型的内存,在内存还没有和具体的变量相绑定之前,内存可以没有类型,实际上纯粹的内存就是没有类型的,内存只是因为和具体的变量相关联后才有了确定的类型。
(5)void类型的正确的含义是不知道类型+不确定类型+还没确定类型,void_a是定义了1个void类型的变量,含义就是说a是1个变量,a肯定有确定的类型,只是目前还不确定a的类型,所以标记为void。
(6)为什么需要void类型,在描述1段还没有具体使用的内存时需要使用void类型;void的1个典型应用案例就是malloc的返回值,我们知道malloc函数向系统堆管理器申请1段内存给当前程序使用,malloc返回的是1个指针,该指针指向申请的那段内存,malloc刚申请的这段内存尚未用来存储数据,malloc函数也无法预知这段内存将来被存放什么类型的数据,所以malloc无法返回具体类型的指针,即返回1个void_*类型,告诉外部其返回的是1段干净尚未确定类型的内存空间,则我们在malloc之后可以给这段内存读写任意类型的数据。
(7)void_*类型的指针指向的内存是尚未确定类型的,因此我们后续可以使用强制类型转换强行将其转为各种类型,即void类型的最终归宿就是被强制类型转换成某个具体类型;void类型使用时一般都是用void_*,而不是仅仅使用void。


38.main/
main.c
/*
 * 公司:XXXX
 * 作者:Rston
 * 博客:http://blog.csdn.net/rston
 * GitHub:https://github.com/rston
 * 项目:main函数传参和void类型
 * 功能:获取main函数的返回值。
 */

#include <stdio.h>

int main(int argc, char **argv)
{
    printf("hello world.\n");

    return 0;
}
*********
main_return.sh
#! /bin/sh
# 获取main函数的返回值

./a.out
echo $?

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值