1.4.3 它是如何工作的
我们先研究一下代码的基本内容,以便了解代码中不同部分的作用以及它们之所以重要的原因。
源代码
首先,我们包含一个名叫stdio.h的头文件,该文件被printf()函数所需要。stdio这个名字表示标准输入输出。由于printf()会在屏幕上打印字符,因此它被归类为一个stdio函数。
代码中包含的另一个头文件是stdlib.h,表示标准库。标准库中涵盖大量的函数,包括atoi()函数,该函数可以用来将字符串或者字符转变成整数。
在此之后,我们添加了一个名为printhelp()的函数原型。对于这一部分,没有什么需要特殊说明的,将函数体放在main()之下,并将函数原型放在开始位置,是一种很好的C编程实践。函数原型会告诉程序的其余部分该函数采用了哪些参数,以及它的返回值类型是什么。
然后,我们声明了main()函数。为了能够解析程序参数,我们将其声明为int main (int argc, char *argv[]),这在Linux中是很常见的。
main()的两个变量argc、argv都具有特殊的含义。第一个变量argc是一个整数,表示传给程序的参数个数。它的最小值为1,即使没有参数传递给程序。第一个参数就是程序本身的名称。
第二个变量(更准确地说是数组)是argv,它包含命令行传给程序的所有参数。正如刚才所提到的,第一个参数argv[0]就是程序名,也就是执行程序的命令行。举个例子,如果以./sum的方式执行程序,那么argv[0]将包含字符串./sum。如果以/home/jack/sum的方式执行程序,那么argv[0]将包含字符串/home/jack/sum。
我们将这个参数(更准确地说是程序名)传递给了printhelp()函数,从而让该函数打印出程序名以及帮助信息。在Linux和UNIX环境上,这是一种很好的做法。
随后,我们进行了简单的合法性检查。它会检查参数个数是否为1。如果是,那么说明用户没有为程序输入任何参数,这将被视为一种错误的操作。因此,我们使用构建的printhelp()函数在屏幕上打印出错误消息。紧接着,main()函数将会返回1,告诉shell或者其他程序这里出现了错误。每当我们使用return语句从main()函数返回时,都会向shell发送退出码并退出程序。这些退出码都具有特殊的含义,我们将在本书后续内容中进行更深入的探讨。简单来说,0表示程序执行正常,而非0则表示程序执行出错。在Linux中,必须使用返回值,这是向其他程序以及shell通知程序执行情况的一种方式。
继续往下,我们执行了for()循环。在这里,我们通过argc获取参数的个数,并遍历参数列表。i=1表示从1开始遍历。不从0开始是因为argv[]数组中的索引0对应的是程序名。索引1表示第一个参数,也就是传给程序的整数。
在for()循环中,我们编写了sum=sum+atoi(argv[i];)。在这里,我们需要重点关注atoi(argv[i])。我们通过命令行传给程序的所有参数都是字符串类型。为了能够对它们进行计算,我们需要将它们转换为整数,而atoi()函数的主要工作就是进行从字符串到整数的转换。atoi()这个函数名正是代表的整数(integer)。
一旦通过printf()将程序的执行结果输出到屏幕上,main函数将返回0,表示程序执行正常。从main()返回时,将从整个进程返回到shell,换句话说,就是返回到程序的父进程。
程序执行和返回值
当我们在$PATH环境变量所设置的目录之外执行程序时,需要在文件名前加上./。
当程序执行完成,它会将返回值返回给shell,而shell会将该返回值保存在变量?中。当另一个程序执行结束后,这个变量的值又会被另一个程序的最新返回值所覆盖。我们通常使用echo来打印环境变量的值,echo是一个直接从shell打印文本和变量到屏幕上的实用小程序。如果要打印环境变量,需要在变量名前添加$符号,例如$?。