C++多文件源程序

一、多文件结构的源代码组织

  一个C++程序开发工程(project)可以包含多个源程序文件,一个源程序文件(.cpp)可以包含多个函数。一个函数只能集中放在一个源程序文件中,不能将其定义代码拆开存放在不同文件中。一个程序开发工程可以包含很多函数,但只能有一个主函数,其中函数名必须为main。

  使用编译器将C++语言翻译成机器语言。编译时,同一源程序文件中的所有函数被统一编译,因此一个源程序文件称为一个编译单元。一个C++ project可以多个源程序文件cpp,每个cpp编译后产生一个目标程序文件(obj)。目标程序是机器语言的程序,通常不同厂家CPU的机器语言是不一样的。相同的C++源程序可被不同的编译器编译,生成不同机器语言的目标程序运行在不同CPU架构上。

1、外部函数和外部全局变量

  在多文件结构中,一个文件中定义的函数可以被其他文件中的函数调用。可被其他文件调用的函数称为外部函数。一个文件中定义的全局变量也可以被其他文件中的函数访问。可被其他文件访问的全局变量称为外部全局变量。调用外部函数需要“先声明、在调用”,访问外部全局变量也需要 “先声明,在访问”。声明的作用是将外部函数或外部全局变量的作用域延申到本文件来。

声明外部函数和外部全局变量的语法细则如下:

  1)声明外部函数原型,声明是可以使用关键字extern,也可以不用,两者的语法作用完全相同。也可以通过头文件将大量外部函数声明进来。

      extren void RectCost();

      extren double CircleCost(double r);

  2) 声明外部全局变量,声明时必须加上关键字extren,另外不能初始化,否则就变成了另一个全局变量定义语句,连接时会出现两个全局变量重名的错误。

      extren double totalCost = 0;

2、静态函数与静态变量

  多文件结构中,源程序文件中定义的函数默认是外部函数,可以被其他文件中的函数调用;所定义的全局变量默认都是外部全局变量,可以被其他文件中的函数访问。外部函数和外部全局变量被多文件结构中的所有文件共享,其他文件只要经过声明就可以使用这些函数和变量。因此多文件结构中所有外部函数和外部全局变量不能重名,外部函数和外部全局变量之间也不能重名。

  某些情况下,程序员需要在源程序文件中定义一些只能自己调用的函数和全局变量时,就可以使用关键字static将他们定义成静态函数静态全局变量。另外C++语言还可以定义静态局部变量

  1)静态函数,定义函数时在函数头前面加关键字static,该函数就被定义成静态函数。静态函数只能被本文件内部的其他函数调用,其他文件不能调用,即使经过声明也不行。

      static void RectCost();

  关键字static将所定义的函数作用域限定在本文件范围内,禁止延申到其他文件。合理定义静态函数,可以防止其他文件对该函数的误调用。不同文件中的静态函数可以重名。

  2)静态全局变量,定义全局变量时前面加关键字static,该全局变量就被定义成静态全局变量。静态全局变量只能被本文件内的函数访问,即使经过声明也不行。

      static double r1,r2;

  3)静态局部变量,定义局部变量时前面加关键字static,该变量就被定义成静态局部变量。局部变量的静态和非静态与全局变量的静态和非静态含义不一样普通局部变量的作用域和生命期都是函数的块作用域(存储在自动存储区,即栈中),静态局部变量程序执行立即分配空间,知道程序执行结束才被释放(同全局变量一样,存储在静态存储区)。静态局部变量的作用域为块作用域,生命期为全局存在。

      static int y = 0;

  函数中的静态局部变量定义语句只会在程序一开始执行一次,后面不会在重复执行。如果函数被多次调用,其中的静态局部变量可以保留上次调用结束时的值,因为它的内存单元在程序执行一开始即被分配并初始化,知道程序执行结束才被释放,其中的数据也会一直保留下来。仔细分析就会发现,静态局部变量实际上是一种被某个特定函数访问的全局变量。

二、编译预处理指令

  在正式编译C++源程序之前,编译器将预先处理一些特殊指令,这些指令的作用是用来告诉编译器如何编译本程序,它们被称为编译预处理指令。编译器在处理完所有的编译预处理指令之后才进行正式编译。常见的编译预处理指令有三种,它们分别是文件包含指令(include)、宏定义指令(#define)和条件编译指令(#ifdef)。

1、文件包含指令

  程序员可以使用文件包含指令将某个指定文件的内容插入到程序代码的当前位置,通常是用于将某头文件(.h)插入到源程序文件(.cpp)中。

      #include<filename>      //缺省路径时,编译器将到标准目录下搜索指定文件。

     或 #include "filename"     ////缺省路径时,编译器将到当前目录下搜索指定文件。如果搜索不到指定文件再去标准目录下搜索。

  文件名通常不写完整的全路径,而是使用默认路径,即只写头文件的文件名。通常头文件被集中存放在两个目录下:一个是C++编译器安装目录的include子目录下,该目录称为标准目录;另一个是源程序文件所在的目录,称为当前目录。文件包含指令以“#”开头,单独写一行,不假分号“;”结束符。

2、宏定义指令

  C++源程序中,允许用一个标识符来表示一段代码文本,这就称为一个。其中标识符为宏名,所白表示的代码文本称为宏文本。

  宏需要先定义在使用。程序员可以通过宏定义指令(#define)来定义一个新的宏,可以通过宏删除指令(#undef)删除一个已经定义的宏。

  预处理时,编译器将源程序中所有的宏名自动替换回原来的宏文本,称为宏替换宏展开。C++语言中由三种形式的宏,分别为无参宏、有参宏和空宏

  1)无参宏

      #define 宏名 宏文本  //宏名应符合命名规则,习惯上用大写字母命名。宏文本所表示的字符串,可以由任意字符组成,不需要加引号。

  2)有参宏

      #define 宏名(参数列表) 宏文本 //参数列表指定若干可被替换的参数,参数之间通过逗号隔开。

      举例: #define AREA(x)  3.14159 *x*x 若参数是一个表达式还可以写成 #define AREA(x)  3.14159 *(x)*(x) 带上括号优先计算。

  3)空宏

      #define 宏名 //空宏不是用于宏替换,而是配合条件编译指令使用

  4)宏删除

      #undef 宏名

3、条件编译指令

  条件编译指令允许程序员将不同版本的源程序编写在同一程序文件中,便于管理和维护修改。

  1)格式一

      #ifdef 宏名

        代码段1

      #else

        代码段2

      #endif

    编译器在编译代码时、如果宏名已经定义,则编译代码段1,否则编译代码段2.这种格式的条件编译指令一般与空宏搭配使用。如果没有代码段2省略#else

  2)格式二

      #if 常量表达式

        代码段1

      #else

        代码段2

      #endif

    编译器在编译代码时、如果常量表达式的结果为0,则编译代码段1,否则编译代码段2。常量表达式只能包含字面常量或符号常量。如果没有代码段2省略#else

  

  

 

原文链接: https://www.cnblogs.com/qlzstudy/p/16456534.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

    C++多文件源程序

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/190314

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月12日 下午4:04
下一篇 2023年2月12日 下午4:04

相关推荐