源程序 C源程序是一条或多条指令、说明和或定义的集合。指令说明在编译之前C的预处理程序处理程序正文时所应执行的特殊动作,说明建立程序所使用的变量、函数和类型的名字和属性。 定义也是定义变量和函数的说明。变量的定义除了给出所说明的变量的名字和类型外,还要给出它的初值,定义迫使变量分配存贮空间。函数的定义说明函数体,它由说明和构成函数的语句组成7个复合语句,函数的定义还给出函数的名字、形式参数和返回值的类型。 可以有任意数目的指令、说明和定义,每一个都必须满足在本书中所描述的相应的语法。在程序中它们能以任何顺序出现,虽然顺序对程序中如何使用变量和函数有一定影响。 有效的程序至少有一个定义和一个函数定义,函数给出程序的动作。下例是一个简单的C源程序。 该源程序定义了名为main的函数,说明了函数printf,变量X和y用变量定义的方法定义,而变量z和w仅仅是被说明而已。 源文件 源程序可以分成一个或多个彼此独立的源文件。一个c源文件是包含一个c源程序的全部或部分的正文文件。例如它可以只包含程序所的几个函数,当编译源程序时,构成源程序的所有源文件必须单独编译,然后再连接。使用第八章预处理程序指令所介绍的ttinchMle指令可以把彼此独立的源文件组合起来,形成一个大的源文件。 源文件可以包含完整的指令、说明和定义的任何组合,诸如函数定义或大的数据结构之类的项不能分于多个源文件中。 源文件可以不包含任何可行语句。有时要把变量的定义放在一个源文件中,而将对这些变量的引用的说明放在另一个文件中是有用的,这使得定义易于查找和修改。同样,人们也常常把常数和宏(在第八章预处理程序指令中讨论)组织到一个include文件中,而在需要的时候再插入到源文件中。 源文件中的指令只对该文件自身和它所包含进来的文件起作用,而且只对文件中跟在它之后那部分正文有用。如果要使一组指令对源程序起作用,那么程序的所有源文件都必须包含这组指令。 下面是一个有两个源文件的源程序的例子。定义函数main()和max()分别在不同的源文件中,而程序的执行从函数main()开始。 在第一个源文件中,函数max()只被说明而未被定义,这就是众所周知的向前说明。函数main()的定义中包含对max()的函数调角。 以开始的行是预处理程序指令,这些指令告诉预处理程序用第一源文件中指定的整数去替换标识符ONE、TWO和THREE。这些指令对第二个源文件没有用。第二个源文件包括函数的定义,该定义满足第一个源文件中对max()的调用。一旦把源文件加以编译,就可以把它们连接成一个程序并投入运行。 程序的执行 每个程序必须有一个主函数(main),该函数用于程序执行的入口点,而且通常是通过直接调用程序中的其它函数来控制程序的执行。程序通常是执行到主函数的末尾便停止了,当然程序也可以在其它点停止,这取决于运行的环境。 源程序常常有多于一个的函数,每个函数完成一个或几个指定的任务,main()函数可以调用这些函数去执行任务。当调用一个函数时,就从被调用函数的第一语句开始执行,当执行到return语句或走到函数末尾时,函数就将控制权归还给调用它的函数。 所有的函数,包括main()函数,都可以说明成带参数的,由其它函数调用的函数从调用函数处收到参数的值。而函数main()的参数可以说明成从程序的外部环境(例如,当执行程序时,从命令行传递参数的值)传递值。 习惯上,主函数的头三个参数的名字说明成argc,argV和envp。参数argc记录传递给主函数的自变量的总数;参数argv是一个指针数组,每个元素指向传递给函数main()的一个自变量的字符串表示;参数envp是一个指针,它指向建立程序运行的环境的字符串值所组成的一个表。 操作系统为argC,argv和envp三个参数提供值,而用户为主函数提供实际的自变量。在特定系统上所使用的传递自变量的约定取决于该系统,而不是取决于C语言。