简单程序设计.
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
extern 数据类型 外部变量[,外部变量2……];
注意:外部变量的定义和说明是两回事。外部变量的定义,必
须在所有的函数之外,且只能定义一次。而外部变量的说明, 出现在要使用该外部变量的函数内,而且可出现多次。 [return]
6.2.2 外部函数
函数无全局与局部之分,一般是可 以共享的。在另一文件中要使用这个函 数,只要说明一下函数原型即可。也就 是C++中函数的说明默认是extern的。所 以可在原型说明时省略前面的extern。 [return]
6.3.1 #include指令
• #include指令告诉预编译程序,将其后的文件 内容插入到当前文件中。一般形式为: • #include<文件名> 或 #include”文件名” • 两者不同在于预编译程序查找文件的路径不同。 前者仅在C++系统目录的include子目录中找; 后者先在用户程序的当前目录下找,若找不到 再到系统目录下找。 • #include指令可以嵌套。所包含文件只要是文 本文件均可。所以除.h外,.txt亦可。 [return]
6.4 生存期
6.4.1 生存期与内存 6.4.2 初始化问题 6.4.3 局部静态变量 [Return]
6.4.1 生存期与内存
内存空间可以分为代码区、全局数 据区、堆区和栈区。不同生存期的变量 存放的内存区域是不同的。
பைடு நூலகம்
6.4.2 初始化问题
具有静态生存期的变量会由系统自 动初始化为0,而系统不对具有局部生存 期和动态生存期的变量进行初始化。
静态存储例:
#include<iostream.h> #define RESET true unsigned counter(bool reset=!RESET) { static unsigned cnt=0; if(reset)return cnt=0; return ++cnt; }
void main() { cout<<' '<<counter(); cout<<' '<<counter(); cout<<' '<<counter(); cout<<' '<<counter(RESET); cout<<' '<<counter(); cout<<' '<<counter(); cout<<'\n'; }
静态局部变量和静态外部变量同属静态存储方式,但两者区 别较大: (1)定义的位置不同。静态局部变量在函数内定义,静态外 部变量在函数外定义。 (2)作用域不同。静态局部变量属于内部变量,其作用域仅 限于定义它的函数内;虽然生存期为整个源程序,但其它函数是 不能使用它的。 静态外部变量在函数外定义,其作用域为定义它的源文件内; 生存期为整个源程序,但其它源文件中的函数也是不能使用它的。 (3)初始化处理不同。静态局部变量,仅在第1次调用它 所在的函数时被初始化,当再次调用定义它的函数时,不再初始 化,而是保留上一次调用结束时的值。而静态外部变量是在函数 外定义的,不存在静态内部变量的“重复”初始化问题,其当前 值由最近一次给它赋值的操作决定。
第 6章
6.1 6.2 6.3 6.4
简单程序设计
程序开发过程 文件之间的信息共享 头文件 生存期
[Return]
6.1 程序开发过程
• C++程序一般是多文件结构的。这样,每个文 件的长度相对较小,功能相对单一,维护方便。 便于多人合作开发。若一个文件的代码有改变 只需重新编译此文件而不必重新编译所有文件。 • 预编译负责处理各个源文件和头文件中的预编 译指令;编译程序将源程序翻译成对应的二进 制代码文件,扩展名为.obj;连接程序将所 有.obj和用到的库文件连接起来,形成一个可 执行文件。 Return]
不同的存储类型
在C语言中,对变量的存储类型说 明有以下四种:自动变量(auto)、寄存器 变量(register)、外部变量(extern)、静态变 量(static)。自动变量和寄存器变量属于动 态存储方式,外部变量和静态内部变量 属于静态存储方式。
内部变量的存储方式
1.静态存储──静态内部变量 (1)定义格式: static 数据类型 内部变量表; (2)存储特点: ①静态内部变量属于静态存储。在程序执行过程 中,即使所在函数调用结束也不释放。换句话说, 在程序执行期间,静态内部变量始终存在,但其它 函数是不能引用它们的。 ②定义若不初始化,则自动赋以"0 "(整型和实 型)或 '\0' (字符型);且每次调用它们所在的函数 时,不再重新赋初值,只是保留上次调用结束时的 值! (3)何时使用静态内部变量: ①需要保留函数上一次调用结束时的值。 ②变量只被引用而不改变其值。
6.2.3 静态全局变量与静态函数
• 若不希望某文件中定义的某些变量或函数被其 它文件使用,可将这些变量或函数定义成静态 (static)的。 • 使用static全局变量和函数的好处: ⑴可将某些实现细节封装进来,既安全又简化了 文件之间的接口; ⑵不同文件可使用同名变量或函数而不必担心名 字冲突。 • [return]
6.4.3 局部静态变量
函数的局部变量一般具有局部生存期,函数执行 结束后其局部状态信息将会丢失。当需要让函数让它 记住上次运行的状态,以便进行一些处理时,可将此 局部变量设为静态。静态局部变量的如下特性: 1.具有静态生存期。即生存期与程序的运行期相同,变量 处于内存的全局数据区,而不在栈区,并且系统自动 将其初始化为0; 2.只被初始化一次; 3.在函数退出后,静态局部变量不被释放,保留其值。下 次进入函数后静态局部变量还能保留它的值。
2.动态存储──自动局部变量(又称自动变量) (1)定义格式:[auto] 数据类型 变量表;
(2)存储特点 1)自动变量属于动态存储方式。在函数中定义的自动变量,只 在该函数内有效;函数被调用时分配存储空间,调用结束就释放。 在复合语句中定义的自动变量,只在该复合语句中有效;退出复 合语句后,也不能再使用,否则将引起错误。 2)定义而不初始化,则其值是不确定的。如果初始化,则赋初 值操作是在调用时进行的,且每次调用都要重新赋一次初值。 3)由于自动变量的作用域和生存期,都局限于定义它的个体内 (函数或复合语句),因此不同的个体中允许使用同名的变量而不 会混淆。即使在函数内定义的自动变量,也可与该函数内部的复合 语句中定义的自动变量同名。
6.3.3 预编译指令
1. 条件编译指令:#if、 #elif、 #endif、 #ifdef、 #ifndef等。用法与if类似,预编 译器可以根据条件确定保留或不保留程 序文件中的某些内容。 2. #define指令
#ifdef ~ #endif和#ifndef ~ #endif
1.一般格式 #ifdef 标识符 程序段1; [#else 程序段2;] #endif 2.功能:当“标识符”已经被#define命令定义过,则编译程序 段1,否则编译程序段2。 利用条件编译,还可使同一源程序即适合于调试(进行程序跟 踪、打印较多的状态或错误信息),又适合高效执行要求。 3.关于#ifndef ~ #endif命令 格式与#ifdef ~ #endif命令一样,功能正好与之相反。
#if ~ #endif
1.一般格式 #if 常量表达式 程序段1; [#else 程序段2;] #endif
2.功能:当表达式为非0(“逻辑真”)时,编译
程序段1,否则编译程序段2。
[return]
常用的头文件
• iomanip.h 含有setw等操纵符,其它功能 与iostream.h相同 • math.h 数学函数 • string.h 字符处理函数 • ctype.h 字符判断及转换函数 • stdlib.h 随机函数、数据类型转换、系统 控制(如exit(1) ) • stdio.h C++的printf和scanf用到
建议:系统不会混淆,并不意味着人也不会混淆,所以尽量少
用同名自动变量!
3.寄存器存储──寄存器变量 一般情况下,变量的值都是存储在内存中的。为提高 执行效率,C语言允许将局部变量的值存放到寄存器中, 这种变量就称为寄存器变量。定义格式如下: register 数据类型 变量表; (1)只有局部变量才能定义成寄存器变量,即全局变 量不行。 (2)对寄存器变量的实际处理,随系统而异。例如, 微机上的MSC和TC 将寄存器变量实际当作自动变量处理。 (3)允许使用的寄存器数目是有限的,不能定义任意 多个寄存器变量。
6.2 文件之间的信息共享
6.2.1 外部变量 6.2.2 外部函数 6.2.3 静态全局变量与静态函数
[Return]
6.2.1
外部变量
在函数外部定义的变量称为外部变量。外部变量不属于 任何一个函数,其作用域是:从外部变量的定义位置开始, 到本文件结束为止。外部变量可被作用域内的所有函数直接 引用,所以外部变量又称全局变量。 (1)外部变量可加强函数模块之间的数据联系,但又使这些函 数依赖这些外部变量,因而使得这些函数的独立性降低。 (2)在同一源文件中,允许外部变量和内部变量同名。在内部 变量的作用域内,外部变量将被屏蔽而不起作用。 (3)定义点前的函数引用这些外部变量时,需要在函数内对被 引用的外部变量进行说明。外部变量说明的一般形式为:
宏定义与符号常量
在C语言中,“宏”分为无参数的宏 (简称无参宏)和有参数的宏(简称有 参宏)两种。
无参宏定义 符号常量 有参宏定义
[Return]
无参宏定义
1.无参宏定义的一般格式
#define 标识符 语言符号字符串
其中:“define”为宏定义命令;“标识符”为所定义的宏名, 通常用大写字母表示,以便于与变量区别;“语言符号字符串”可 以是常数、表达式、格式串等。 2.使用宏定义的优点 (1)可提高源程序的可维护性 (2)可提高源程序的可移植性 (3)减少源程序中重复书写字符串的工作量
[Return]
外部变量的存储方式
• 外部变量属于静态存储方式: • ( 1 )静态外部变量 ── 只允许被本源文件中 的函数引用 • 其定义格式为: static 数据类型 外部变量 表; • ( 2 )非静态外部变量 ── 允许被其它源文件 中的函数引用 • 定义时缺省static关键字的外部变量,即为非 静态外部变量。其它源文件中的函数,引用非静 态外部变量时,需要在引用函数所在的源文件中 进行说明: • extern 数据类型 外部变量表; • 注意:在函数内的extern变量说明,表示引 用本源文件中的外部变量!而函数外(通常在文 件开头)的extern变量说明,表示引用其它文件
务必牢记:把局部变量改变为静态内部变量后,
改变了它的存储方式,即改变了它的生存期。把外部 变量改变为静态外部变量后,改变了它的作用域,限 制了它的使用范围。因此,关键字“static” 在不同的 地方所起的作用是不同的。
[Return]
6.3 头文件
一个大程序,通常分为多个模块,并由多个程序 员分别编程。有了文件包含处理功能,就可以将多个 模块共用的数据(如符号常量和数据结构)或函数, 集中到一个单独的文件中。这样,凡是要使用其中数 据或调用其中函数的程序员,只要使用文件包含处理 功能,将所需文件包含进来即可,不必再重复定义它 们,从而减少重复劳动。 6.3.1 #include指令 6.3.2 头文件内容 6.3.3 预编译指令 [Return]
3.说明
(1)宏名一般用大写字母表示,以示与变量区别。但这并非是规定。 (2)宏定义不是C语句,所以不能在行尾加分号。否则,宏展开时, 会将分号作为字符串的1个字符,用于替换宏名。 (3)在宏展开时,预处理程序仅以按宏定义简单替换宏名,而不作 任何检查。如果有错误,只能由编译程序在编译宏展开后的源程序时发 现。 (4)宏定义命令#define出现在函数的外部,宏名的有效范围是:从 定义命令之后, 到本文件结束。通常,宏定义命令放在文件开头处。 (5)在进行宏定义时,可以引用已定义的宏名 。 (6)对双引号括起来的字符串内的字符,即使与宏名同名,也不进 行宏展开。
6.3.2 头文件内容
一般放入以下内容: ⑴预编译指令:#infine、#ifdef、#endif、#include ⑵函数声明 ⑶内联函数定义 ⑷类型定义 ⑸外部数据声明 ⑹常量定义 ⑺注释 总之,多个文件可能要使用的一般放到头 文件中;而放入后若多个文件用到此头文件会 引进冲突的内容则不应放入头文件中。 [return]