310 likes | 488 Views
第 6 章 程序结构. 6.1 多文件结构 6.2 外部存储类型 6.3 静态存储类型 6.4 作用域与可见性 6.5 头文件 6.6 编译预处理. 2. 6.1 多文件结构. 一个源程序文件由一个或多个 函数组成 源程序文件是独立的 编译单位 一个 C++ 程序由一个或多个源程序文件组成, 称为“工程文件”( .prj ) 程序是独立的 运行单位 一个源程序文件可以为多个 C++ 程序公用. f_main.cpp. f_fun.cpp. 3. 一个简单多文件程序. void fun () ;
E N D
第 6 章 程序结构 6.1多文件结构 6.2外部存储类型 6.3静态存储类型 6.4作用域与可见性 6.5头文件 6.6编译预处理
2 6.1 多文件结构 一个源程序文件由一个或多个函数组成 源程序文件是独立的编译单位 一个C++程序由一个或多个源程序文件组成, 称为“工程文件”(.prj) 程序是独立的运行单位 一个源程序文件可以为多个C++程序公用
f_main.cpp f_fun.cpp 3 一个简单多文件程序 void fun () ; main () { fun () ; } ex6_1.prj 组成 在此是必须的 # include <iostream.h> void fun () { cout << ” This is a simple project.” << endl ; return ; }
4 1. 建立工程 Project | Open Project (在Project 菜单选取Open Project 项目) 在Open Project File对话框输入工程文件名, 如: ex6_1.prj , 屏幕上出现工程文件窗口 在 TC3.0 建立工程的方法: 2. 创建 cpp 文件 在工程窗口底部选择 Add 命令, 添加 cpp 文件, 如 f_main.cpp 和 f_fun.cpp, 进入编辑环境输入程序代码 * 3. 编译连接工程文件 Compile | Make 自动连接编译,生成 .EXE文件 4. 运行 Run | Run
5 在 TC3.0 打开工程的方法: Project | Open Project 在 Open Project File 对话框的 File 列表中文件名 打开后的工程可以利用工程文件窗口进行编辑, 然后重新编辑连接、运行
6 6.2 外部存储类型 1. 一个工程的各文件可以共享全局变量 方法: 在其中一个文件定义全局变量,不能在其它文件重定义 需要共享的文件中作外部变量声明 extern <变量名> Example6_2
7 Example6_2 Ex6_2.prj // BF.CPP extern int n ; // 说明外部变量 void funb () { n += n ; return ; } // AF.CPP # include <iostream.h> void funb() ;// 说明外部函数 void func() ; int n; // 全局变量 main () { n = 3 ; funb() ; func () ; cout <<”n= ” << n << endl ; } // CF.CPP extern int n ; // 说明外部变量 void func() { n *= n ; return ; }
8 6.2 外部存储类型 2. 调用其它文件的函数 方法: 需要调用其它文件函数作外部函数声明 [extern ] <函数名> ; 默认声明为 extern 的 Example6_2
9 6.3 静态存储类型 1. 静态全局变量 形式 static <类型> <变量名> ; 说明 文件中的定义全局变量 对其它文件无效 Example6_3
10 file1.cpp # include < iostream.h > extern fn () ; //调用外部函数 int n ; //全局变量 main () { n = 20 ; cout << “n = ” << n << endl ; fn () ; } ex6_3.prj Example6_3 file2.cpp # include < iostream.h > static int n ;//静态全局变量 void fn() { n++ ; cout << “static n = ” << n << endl ; return ; }
11 6.3 静态存储类型 2. 静态函数 形式 static <类型> <函数名> ; 说明 对函数原型冠以 static 修饰 该函数不能被其它文件调用 Example6_4
12 ex6_4_2.cpp # include < iostream.h > static void statfn( ) ; void fn ( ) ; void fn ( ) { statfn ( ) ; cout << “ This is fn() \n” ; return ; } void statfn ( ) { cout << “ This is static fn ( ) \n ” ; return ; } ex6_4.prj Example6_4 ex6_4_1.cpp # include < iostream.h > void fn ( ) ; void main ( ) { fn ( ) ; } 在ex6_4_1中 通过 fn () 调用了 statfn()
13 6.4 作用域与可见性 作用域 标识符在程序中的有效范围 可见性 标识符在作用域范围内的可访问性
14 6.4 作用域与可见性 作用域 按有效范围: 局部作用域 函数作用域 函数原型作用域 文件作用域
15 1. 局部作用域 —— 标识符在语句块内有效 i 的作用域为 for的外一层块 void fn3() { int n; for ( int i = 0; i <10; i ++ ) { int hn; if ( i%2 ) n++ ; } hn = n / 2 ;// error n = i ; // ok } Example6_5 例: void fn1() { int x = 1; if (x>y) cout << x<<endl; else cout <<y<<endl; } n 的作用域仅为 该语句 hn 的作用域为 花括号语句块 void fn2() { if (x>y) int n= x ; else n = y;// error }
16 2. 函数作用域 例: void fn() { goto s ; int b; cin >> b; if ( b > 0 ) { s : goto end ; } end : cout << “ All right \n” ; } 标识符在整个函数体内有效 标号是唯一具有函数作用域的标识符 注意 局部量不一定具有函数作用域 局部量的作用域与定义位置有关
17 3. 函数原型作用域 —— 函数原型声明的参数作用域仅在圆括号内 例: void area ( double width, double length ) 等价于: void area ( double , length )
18 4. 文件作用域 在所有函数之外定义的标识符,作用域为从说明点开始至文件结束 若源文件嵌入头文件,则头文件的标识符作用域延伸至源文件
19 可见性 标识符在作用域内可见 嵌套作用域若有同名标识符,以屏蔽外层标识符原则可见
头文件 A 头文件 B 头文件 C .h 文件 实现文件 A 实现文件 B 实现文件 C .prj 文件 主 文 件 20 6.5 头文件 C++ 在软件系统组织上,从程序到文件都有极大灵活性 一个好的软件系统应当分解为各种同构逻辑文件
21 头文件通常提供以下接口: 类声明 函数声明 数据声明 6.5 头文件 一个头文件加上适当的注释,可以作为一个小型用户指南 Example6_6
myarea.h mycircle.cpp myrect.cpp ex6_6.prj mymain.cpp 22 Example6_6计算圆面积和矩形面积
符号表 源程序 目标程序 词法分析 语法分析 代码生成 预处理器 错误信息 错误处理程序 23 6.6 编译预处理 C++编译器工作过程
24 预处理器与预处理指令 预处理器作用 改善程序的组织和管理 预处理指令 由编译器支持,不是C++语言部分 所有编译指令以 #开头 每条指令单独占一行
25 常用预处理指令 #include #else #define #elif #undef #endif #if #error
26 1. #include 嵌入指令 作用: 用于支持多文件形式组织的C++程序 指示C++编译器将一个文件的内容嵌入到该指令所在位置 格式1:#include <文件名> 用于嵌入C++系统提供的头文件。 从C++系统目录的 INCLUDE 目录搜索指定文件 格式2:#include “文件名” 用于嵌入程序员建立的头文件。 首先搜索当前目录 然后搜索C++系统目录的 INCLUDE 目录
27 2. #define 和 #undef #define 以指定正文串替换标识符 格式1:#define 标识符 替换正文 此指令用C++的 const 语句代替 格式2:#define 标识符(参数表)替换正文 此指令用C++的 inline 函数代替 #undef 删除 #define 的宏替换
28 3. #if 和 #endif 格式:#if 常数表达式 程序正文1 #endif 程序正文2 功能: “常数表达式”非 0 ,“程序正文1”和“程序正文2”都被编译器编译 “常数表达式”为 0 ,仅编译“程序正文2” 示例
29 3. #if 和 #endif # include <iostream.h> # define N 2 // 以 2 替换 N int main ( ) { # if N > 3 cout <<“I am not compiled !” <<endl ; # endif cout << “All done !” << endl ; return; } 预处理后程序正文 int main ( ) { cout << “All done !” << endl ; return; }
30 4. #else 和 #elif 格式1:#if 常数表达式 程序正文1 #else 程序正文2 #endif 格式2:#if 常数表达式1 程序正文1 #elif 常数表达式2 程序正文2 #else 程序正文3 #endif 功能: 根据“常数表达式”的值,提供编译“程序正文”的 2 种或 3 种选择
31 5. #error 格式: #error 字符序列 功能: 显示“字符序列”,然后停止对程序的编译。