组织程序结构的相关技术.ppt

上传人:max****ui 文档编号:14567472 上传时间:2020-07-24 格式:PPT 页数:23 大小:415.81KB
返回 下载 相关 举报
组织程序结构的相关技术.ppt_第1页
第1页 / 共23页
组织程序结构的相关技术.ppt_第2页
第2页 / 共23页
组织程序结构的相关技术.ppt_第3页
第3页 / 共23页
点击查看更多>>
资源描述
第7章 组织程序结构的相关技术,C和C+中允许使用相当数量的以#开头的预处理器指令,包括最常见的宏定义和#include指令。这些指令不是C+语句,在源程序被真正编译之前,由一个预处理器将其替换成标准C+程序,故称为预处理(器)指令或命令。,7.1 宏定义与条件编译,7.1.1 宏定义,例如: #define _STRING_H /用于条件编译目的是说明常量_STRING_H是否曾经被定义过; #define True 1 #define abs(x) (x)0?(x):-(x) 这种替换中不会发生任何计算行为。因为宏定义中没有类型检查,目前的第二、三种宏定义已基本被const常量和inline函数取代。,7.1.2 条件编译,条件编译指令使预处理器能够有选择地取舍参加编译的代码,是为了提高程序的可移植性而设置的指令。 #ifdef 宏名 statements_1 #else statements_2 #endif 其中含义:如果已定义了宏,保留语句组statements_1部分参加编译,否则语句组statements_2部分参加编译(如果有#else部分)。 条件编译指令会出现在每一个C或C+头文件中。,7.2 头文件包含,可以用一条指令代替大量的重复代码,减轻了重复声明的负担。 例如,如果两个程序文件中都使用了函数print或类A,那么,每个文件中都需要插入函数的声明和类的定义。 可以利用头文件将函数声明、类型定义等集中起来,再以头文件包含指令插在程序开头。,7.2.1 头文件包含指令,头文件包含指令有如下两种格式: #include #include #include “文件名” #include d:userx.h 两种格式区别: 第一种格式一般用于包含系统头文件,主要在系统目录中查找文件,速度较快, 第二种格式用于用户自定义头文件。主要在更多的目录下查找,如程序文件所在的目录等,因此会消耗更多的查找时间。 在预处理时,系统将用查找到的文件内容替换掉文件包含指令。,7.2.2 新旧库头文件,标准C+已经将这些内容重新在std名字空间中做了定义。 C的头文件:应在原来的C头文件前加“c”, 如#include ; 旧版C+头文件:文件名带“.h”, 如#include ; 标准库C+头文件:文件名不带“.h”, 如#include 。 事实上,#include 形式的文件包含虽然可用,但此时使用的C函数没有包装在std名字空间里。,7.2.3 类定义与实现的分离,类定义与实现部分通常总是分离的 类的定义构成.h文件,类的实现形成.cpp文件。 为了使用类的定义,.h文件必须对使用者公开,这样,类的程序文件中采用文件包含指令包含头文件,而.cpp文件一般编译成机器代码,使源程序代码得到了保护。 与商业性相关的类定义及其实现构成了类库 主要的C+类库包括微软公司的MFC和Borland公司的OWL,分别集成在他们自己的C+产品中,为软件开发工作提供支持。,7.2.4 头文件中的内容,头文件中的基本内容是“声明”,可以包含如下的内容:,函数声明,如“void print(int);”; 类型声明,如“class A;”,说明A是一个类; 全局数据声明,如“extern int m; extern double a;” 内联函数定义,如“inline void fn() . ”; 类模板定义,如“template class X . ;”; 类型定义,如“class Y . ;enum Z . ;”; 全局常量定义,如“const double pi = 3.14;”; 名字空间定义,如“namespace S . ”。,7.2.5 一个头文件示例,条件编译的作用是使得第二次包含此头文件时,所有内容不再参加编译.,一个包含类定义的头文件aclass.h可组织成如下形式: #ifndef _ACLASS_H/如果未定义宏_ACLASS_H,下面内容参加编译 #define _ACLASS_H/定义宏 #include /函数或类定义中使用的头文件 class A; void print(A #endif/条件编译结束,在函数print和类A的实现文件aclass.cpp中,只要包含如下命令,就可以实现对函数和类的声明了: #include aclass.h,7.3 对象的构造与析构次序,#include using namespace std; class A int a; public: A(int av):a(av) cout A constructor; a= a . endl; ; A a1(1);/进入main函数之前初始化 int main() cout Enter main function.n; A a2(2);/以下3个局部对象按先后顺序初始化 static A a3(3); A a4(4); for(int k=0; k3; k+) A a5(5);/初始化三次 static A a6(6); /静态对象只初始化一次 ,A constructor; a=1. Enter main function. A constructor; a=2. A constructor; a=3. A constructor; a=4. A constructor; a=5. A constructor; a=6. A constructor; a=5. A constructor; a=5.,局部的自动对象在程序流程离开所在块时被拆除。 外部对象和静态对象在程序运行结束时被拆除。 动态对象在用delete释放或程序运行结束时被拆除。 对象的拆除次序总是与构造次序相反的,即最先构造的对象最后拆除,包括并列、有继承关系和一个对象是另一个对象的成员等所有情况。,7.4 名字冲突、屏蔽与名字空间,在C+中有多种作用域。 在同一作用域内,数据名(常量和变量)和函数名属于一类,彼此不能重复,类型名(使用class、struct、union和enum定义)属于另一类,彼此也不能重复。 但不同种类的名字可以相同(如变量名和类型名可相同),不同作用域内的名字也可以相同。,7.4.1 名字冲突及对策,1 局部名对外部名的屏蔽作用,double A, x;/外部定义变量 class A ;/外部定义类型 int main( ) class A ;/内部定义类型 int x;/main函数体局部定义变量 A a;/局部定义的A屏蔽外部的A for(int k=0; k10; k+) double x = 1;/块内定义 cout x+;/块内的x屏蔽main及以外的x cout x;/main的x屏蔽外部x ,2 数据名和函数名冲突 在内部数据或函数名屏蔽了外部类型名时,应使用类型名的全名(带class、struct、union或enum关键字)来表示类型名; 在局部定义的类型名屏蔽了外部数据或函数名时,以域解析符“:”进行区分。,class X ;/外部类型 class Y ;/外部类型 int Y = 1;/外部变量 void fn(int X)/形参变量X class X x1; /形参变量X屏蔽了类型名X,采用类型全名 X+; /形参变量X class Y y1;/必须用全名与外部变量Y相区别 :Y = 2; /用域解析符:引用外部变量Y ,7.4.2 定义和使用名字空间,1 名字空间的定义 同一种类的名字在其中必须唯一的作用域称为名字空间。 此部分内容要求学生自学。,2 使用名字空间中的定义 此部分内容要求学生自学。,7.5 C+与C的混合编程,对用于C+的C语言代码要做适当处理,方法是将C语言的代码进行下述形式的修饰:,extern C /C语言的代码(外部函数) 修饰中的extern说明被修饰的C语言代码中的名字应该是外部的,而”C”则说明这些名字按C语言而非C+语言的方式处理。,7.5.1 extern的作用,extern是C/C+语言中表明函数和全局变量作用域(可见性)的关键字,作用是告诉编译器,它所声明的函数或变量是全局的(或称外部的),可以在本文件(模块)或其它文件(模块)中使用。,1 用extern声明外部变量 extern int a; 编译器对这样声明的变量a并不分配内存空间,而是在各模块中查找匹配的定义(int a)。 如果在其它地方定义了外部变量a,上述语句是声明语句(不能初始化);如果没定义外部变量a,上述语句就是变量a的定义语句(可以包含初始化部分)。,2 用extern声明外部函数 extern int fn(int); 与没有extern修饰的效果相同,表示函数fn可以在任何模块中引用。 与extern相对的是static关键字,如果一个外部变量或函数用static修饰,表明此变量或函数仅可以在定义它的模块中使用,自然不可以被extern “C”修饰。,3 外部引用方法 在模块的头文件中对本模块提供给其它模块引用的函数和全局变量以关键字extern 声明。,B.cpp的实现: int a = 10; int fn(int x) cout x; B.h的组织: extern int a;/声明 extern int fn(int x); 引用a和fn的A.cpp可如下实现: #include b.h int main() fn(a); ,在编译时,虽然模块A中找不到fn和a,但系统不会报错,可以在连接阶段从模块B编译生成的目标代码中找到它们。,7.5.2 用extern “C”修饰C的代码,为了使一个C语言模块B.c能够在C和C+环境下使用,应该按如下方式组织它的头文件B.h:,#ifndef _B_H #define _B_H void func(int x, double y); #endif,#ifndef _B_H #define _B_H extern C void func(int x, double y); #endif,#ifndef _B_H /防止重复定义 #define _B_H #ifdef _cplusplus/检测编译模式 extern C #endif void func(int x, double y);/函数声明部分 #ifdef _cplusplus/检测编译模式 #endif #endif,
展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 图纸专区 > 课件教案


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!