第 2 章 基 本 概 念
本 章 意 在 解 释 对 理 解 C++ 至 关 重 要 的 一 些 概 念 ,C 程 序 员 将 对 这 些 概 念 中 的 很 多内 容 非 常 熟 悉 , 但 存 在 一 些 细 微 的 差 别 可 能 导 致 意 想 不 到 的 程 序 结 果 , 包 含 了 以下 论 题 :
-
术 语
-
说 明 和 定 义
-
范 围
-
程 序 和 连 接
-
开 始 和 结 束
-
存 储 类
-
类 型
附 加 的 论 题 包 括 l 值 、 r 值 和 数 值 范 围 界 限 。
术 语
本 书 所 使 用 的 C++ 术 语 在 表 2.1 中 给 出 了 定 义 :
表 2.1 C++ 术 语
术 语 含 义
说 明 说 明 向 一 个 程 序 引 入 名 称 及 它 们 的 类 型 , 而 不 必 定 义 相 关联 的 对 象 或 函 数 。 但 很 多 说 明 被 作 为 定 义
定 义 定 义 提 供 信 息 而 允 许 编 译 器 为 对 象 分 配 存 储 器 或 为 函 数产 生 代 码
生 存 期 一 个 对 象 的 生 存 期 是 对 象 存 在 包 括 创 建 和 析 构 的 时 间 阶段
连 接 名 称 可 以 有 外 部 连 接 、 内 部 连 接 或 无 连 接 , 在 一 个 程 序 内( 一 套 转 换 单 元 ), 只 有 带 外 部 连 接 的 名 称 才 表 示 相 同 的 对象 或 函 数 。 在 一 个 转 换 单 元 内 , 带 有 内 部 或 外 部 连 接 的 名称 均 可 表 示 相 同 的 对 象 或 函 数 ( 当 函 数 重 载 时 除 外 ) 。 ( 关于 转 换 单 元 的 更 多 信 息 , 参 阅 本 书 后 面 “ 预 处 理 器 参 考 ” 中 “ 翻 译 阶 段 ” ) 。 无 连 接 的 名 称 只 表 示 唯 一 的 对 象 或 函数
名 称 名 称 表 示 一 个 对 象 、 函 数 、 重 载 的 函 数 集 、 枚 举 元 、 类型 、 类 成 员 、 模 板 、 值 或 标 号 、 C++ 程 序 用 名 称 指 出 与 它们 相 关 联 的 语 言 元 素 。 名 称 可 以 是 类 型 名 称 或 标 识 符
续 表对 象 一 个 对 象 是 用 户 定 义 类 型 ( 一 个 类 类 型 ) 的 一 个 实 例 ( 一 个
数 据 项 ) 。 一 个 对 象 和 一 个 变 量 之 间 的 区 别 是 变 量 保 留 状态 信 息 , 而 对 象 还 可 以 拥 有 动 作 。 本 手 册 给 出 的 对 象 和 变量 之 间 的 区 别 是 :“ 对 象 ” 指 用 户 定 义 类 型 的 实 例 , 而“ 变量 ” 指 基 本 类 型 的 实 例 。 在 对 象 或 变 量 均 可 用 情 况 下 , 术语 “ 对 象 ” 被 用 作 为 包 容 性 术 语 , 意 为 “ 对 象 或 变 量 ”
范 围 名 称 只 能 在 程 序 上 下 文 的 特 定 区 域 内 使 用 , 这 些 区 域 被 称为 名 称 的 范 围
存 储 类 被 命 名 的 对 象 的 存 储 类 指 其 生 存 期 、 初 始 化 及 在 某 特 定情 况 下 指 其 连 接
类 型 带 有 相 关 类 型 的 名 称 指 的 是 存 储 在 一 个 对 象 中 或 由 一 个函 数 返 回 的 值 的 含 义
变 量 一 个 变 量 是 一 个 基 本 类 型 ( 如 int 、 float 或 double) 的数 据 项 , 变 量 存 储 状 态 信 息 但 不 为 信 息 如 何 被 处 理 而 定 义动 作 。 看 前 面 列 出 的 “ 对 象 ” 项 来 获 得 有 关 术 语 “ 变 量 ” 和 “ 对 象 ” 是 如 何 在 本 文 档 中 被 运 用 的
说 明 和 定 义
说 明 告 诉 编 译 器 一 个 程 序 元 素 或 名 称 存 在 , 定 义 指 定 名 称 描 述 的 是 什 么 代 码 或 数据 , 一 个 名 称 必 须 先 说 明 而 后 才 能 使 用 。
说 明
一 个 说 明 向 一 个 程 序 中 引 入 一 个 或 多 个 名 称 , 说 明 在 一 个 程 序 可 出 现 不 止 一 次 , 因 此 , 可 以 为 每 个 编 译 单 元 说 明 类 、 结 构 、 枚 举 类 型 和 其 它 用 户 定 义 类 型 。 多 说明 的 限 制 是 所 有 说 明 必 须 可 标 识 。 说 明 还 可 作 为 定 义 , 除 了 以 下 说 明 :
-
是 一 个 函 数 原 型 ( 没 有 函 数 体 的 函 数 说 明 )
-
有 extern 指 示 符 但 没 有 初 始 表 达 式 ( 对 象 和 变 量 ) 或 函 数 体 ( 函数 ), 这 意 味 着 该 定 义 在 当 前 转 换 单 元 里 不 是 必 须 的 , 且 给 出 了 名 称 外 部连 接 。
-
是 类 说 明 内 部 的 静 态 数 据 成 员 。
由 于 静 态 类 数 据 成 员 是 由 类 的 所 有 成 员 共 享 的 离 散 变 量 , 它 们 必 须 在 类 说 明 外 部加 以 定 义 和 初 始 化 ( 关 于 类 和 类 成 员 的 更 多 的 信 息 参 见 第 8 章 “ 类 ” ) 。
-
是 一 个 不 带 定 义 的 类 名 说 明 , 例 如 class T;
-
是 typedef 语 句说 明 同 时 也 是 定 义 的 例 子 有 :
// 说 明 和 定 义 整 型 变 量 i 和 j int i;
int j=10;
// 说 明 枚 举 suits
enum suits {Spades=1,Clubs,Hearts,Diamonds};
// 说 明 类 CheckBox
class CheckBox:public Control
{
public:
Boolean IsChecked();
virtual int ChangeState()=0;
}
有 些 说 明 不 是 定 义 :
extern int i;
char *strchr(const char *Str,const char Target);
定 义
一 个 定 义 是 一 个 对 象 或 变 量 、 函 数 、 类 或 枚 举 的 唯 一 规 格 , 由 于 定 义 必 须 唯 一 , 所 以 一 个 程 序 对 于 一 给 定 的 程 序 元 素 只 能 包 含 一 个 定 义 。
说 明 和 定 义 之 间 可 以 是 多 对 一 的 关 系 。 有 两 种 情 况 下 一 个 程 序 元 素 可 被 说 明 但不 被 定 义 :
-
函 数 被 说 明 但 从 来 没 有 用 函 数 调 用 或 带 有 函 数 地 址 的 表 达 式 引 用过 。
-
一 个 类 仅 用 于 其 定 义 不 要 求 被 知 道 的 情 况 , 但 是 , 类 必 须 被 说 明 , 以下 代 码 描 述 了 这 种 情 况 :
class WindowCounter;// 前 向 引 用 , 没 有 定 义
class Window
{
static WindowCounter WindowCounter;//WindowCounter 定 义 不 被 要 求
}
范 围
C++ 的 名 称 仅 能 用 于 一 个 程 序 的 特 定 区 域 , 这 个 区 域 被 称 为 名 称 的 “ 范 围 ”。 范 围确 定 一 个 不 表 示 静 态 范 围 的 对 象 的 名 称 的 生 存 期 , 范 围 还 指 出 了 当 类 构 造 和 析 构函 数 被 调 用 时 , 以 及 对 范 围 而 言 是 局 部 的 变 量 被 初 始 化 时 一 个 名 称 的 可 见 性 ( 详见 第 11 章 “ 特 殊 成 员 函 数 ” 中 “ 构 造 ” 和 “ 析 构 ” 部 分 ) 。
有 五 种 范 围 :
- 局 部 范 围 , 在 一 个 块 内 说 明 的 名 称 仅 在 此 块 中 以 及 包 含 在 此 块 中 的块 内 是 可 访 问 的 , 且 仅 从 说 明 后 开 始 。 一 个 函 数 在 函 数 最 外 层 块 范围 内 的 普 通 参 量 的 名 称 具 有 局 部 范 围 , 就 好 象 它 们 在 包 含 函 数 体 的块 内 被 说 明 一 样 , 考 虑 以 下 代 码 段 :
{
int i;
}
由 于 i 的 说 明 包 含 在 花 括 号 括 起 的 块 内 , 所 以 i 有 局 部 范 围 而 且 永 远 不 能 被 访 问 , 因 为 在 闭 花 括 号 前 没 有 代 码 对 其 进 行 访 问 操 作 。
- 函 数 范 围 , 标 号 是 唯 一 具 有 函 数 范 围 的 名 称 , 它 们 可 在 一 个 函 数 内 的
任 意 位 置 被 使 用 , 但 在 函 数 外 部 则 不 能 访 问 。
-
文 件 范 围 , 任 何 在 所 有 块 或 类 的 外 部 说 明 的 名 称 具 有 文 件 范 围 , 在 其说 明 后 , 在 转 换 单 元 的 任 何 位 置 均 可 访 问 。 带 有 文 件 范 围 的 不 说 明静 态 对 象 的 名 称 通 常 被 称 为 “ 全 局 ” 文 字 。
-
类 范 围 , 类 成 员 名 具 有 类 范 围 。 类 成 员 函 数 仅 能 用 对 象 上 的 成 员 选择 运 算 符 (. 或 ->) 或 成 员 指 针 运 算 符 (.* 或 ->*) 或 指 向 那 个 类 的 对 象的 指 针 进 行 访 问 , 非 静 态 类 成 员 数 据 被 认 为 相 对 于 那 个 类 的 对 象 是局 部 的 。
考 虑 以 下 类 说 明 :
class Point
{
int x ;
int y ;
}
类 成 员 x 和 y 被 认 为 是 在 类 Point 范 围 内 。
- 原 型 范 围 , 在 函 数 原 型 中 说 明 的 名 称 仅 到 了 原 型 结 尾 处 才 是 可 见的 。 以 下 原 型 说 明 了 两 个 名 称 (szDest,szSource); 这 些 名 称 在 原 型结 尾 处 便 超 出 范 围 了 :
char *strcpy(char *szDest,const char *szSource);
说 明 点
- 个 名 称 被 认 为 就 在 其 说 明 符 后 在 其 ( 可 选 的 ) 初 始 化
之 前 马 上 说 明 。 ( 有 关 说 明
符 的 更 多 信 息 参 见 第 7 章 “ 说 明 符 ” ) 。 一 个 枚 举 器 被 认 为 应 在 命 名 它 的 标 识 符后 , 但 在 其 ( 可 选 的 ) 初 始 化 之 前 立 即 说 明 。
考 虑 这 个 例 子 :
double dVar=7.0;
{
void main()
{
double dVar=dVar;
}
如 果 说 明 点 在 初 始 化 之 后 , 则 局 部 dVar 将 被 初 始 化 为 7.0, 即 全 局 变 量 dVar 的值 。 但 是 , 实 际 并 非 如 此 , 所 以 dVar 被 初 始 化 为 一 个 未 定 义 的 值 。
枚 举 遵 循 同 样 的 规 则 , 但 是 , 枚 举 器 被 输 出 到 枚 举 的 包 含 范 围 外 。 在 下 例 中 枚 举元 素 Spades 、 Clubs 、 Hearts 和 Diamonds 被 说 明 , 因 为 枚 举 器 被 输 出 到 封 闭 的范 围 外 , 它 们 被 认 为 具 有 全 局 范 围 。 例 中 的 标 识 符 已 经 在 全 局 范 围 被 定 义 。
考 虑 以 下 代 码 :
const int Spades=1,Clubs=2,Hearts=3,Diamonds=4;
enum Suits
{
Spades=Spades, // 错误
Clubs, // 错 误
Hearts, // 错 误
Diamonds // 错 误
}
由 于 在 前 面 代 码 中 标 识 符 已 经 在 全 局 范 围 内 被 定 义 , 所 以 产 生 出 错 信 息 。
注 意 : 用 相 同 的 名 称 指 定 不 止 一 个 的 程 序 元 素 , 例 如 一 个 枚 举 器 和 一 个 对 象 , 这 都被 认 为 是 很 糟 的 编 程 方 式 , 应 当 避 免 使 用 。 在 前 例 中 , 这 种 方 式 导 致 出 错 。
隐 藏 名 称
你 可 以 通 过 在 一 个 包 围 的 块 内 说 明 名 称 来 隐 藏 该 名 称 , 在 图 2.1 中 ,i 在 更 内 层的 块 内 又 被 说 明 了 , 而 隐 藏 了 在 较 外 层 块 范 围 内 与 i 相 关 的 变 量 。
图 2.1 块 范 围 和 名 称 隐 藏
图 2.1 中 给 出 的 程 序 输 出 为 :
i=0 i=7 j=9 i=0
注 意 : 参 量 szWhat 被 认 为 在 函 数 范 围 内 , 因 此 , 它 被 看 成 好 象 是 在 函 数 的 最 外 层
块 内 被 说 明 的 。
具 有 文 件 范 围 的 隐 藏 名 称
你 可 以 通 过 在 块 范 围 内 明 确 地 说 明 相 同 的 名 称 而 隐 藏 带 文 件 范 围 的 名 称 。 但 是文 件 范 围 名 称 可 以 使 用 范 围 分 辨 运 算 符 (::) 进 行 访 问 。 例 如 :
#include <iostream.h>
int i=7; //i 具 有 文 件 范 围 即 在 所 有 的 块 外 部 说 明 的void main(int argc, char *argv[])
{
int i=5; //i 具 有 块 范 围 , 隐 藏 了 具 有 文 件 范 围 的 i
cout << " Block_scoped i has the value : " << i << "\n" ;
cout << " File_scoped i has the vaIue : " << ::i << "\n" ;
}
前 面 代 码 的 结 果 是 :
Block_scoped i has the value : 5 File_scoped i has the value : 7
隐 藏 类 名
你 可 以 通 过 在 相 同 的 范 围 内 说 明 一 个 函 数 、 对 象 或 变 量 、 或 者 枚 举 器 来 隐 藏 类名 。
当 然 , 类 名 还 可 以 通 过 使 用 关 键 字 class 前 缀 进 行 访 问 。
// 在 文 件 范 围 说 明 类 Account class Account
{
public:
Account(double InitialBaIance)
{ balance = InitialBalance;}
double GetBalance()
{ return balance;} private:
double balance;
};
double Account=15.37 // 隐 藏 类 名 Account
void main()
{
class Account checking(Account); // 限 定 Acconut 为 类 名
cout << "Opening account with balance of:"
<< checking.GetBalance() << "\n";
}
注 意 , 类 名 (Account) 在 任 何 位 置 被 调 用 时 , 都 要 用 关 键 字 class 将 其 与 文 件 域变 量 Account 区 别 开 来 , 当 类 名 出 现 在 范 围 分 辩 运 算 符 (::) 的 左 侧 时 不 用 此 规
则 。 范 围 分 辩 运 算 符 左 侧 的 名 称 总 被 认 为 是 类 名 , 以 下 例 子 说 明 如 果 用 关 键 字class 来 说 明 一 个 类 型 Account 的 对 象 的 指 针 :
class Account * Checking = new class Account(Account);
上 述 语 句 中 的 Account 在 初 始 化 器 中 ( 在 圆 括 号 内 ) 具 有 文 件 范 围 , 类 型 为double 。
注 意 : 在 这 个 例 子 中 , 标 识 符 名 称 重 新 使 用 认 为 是 糟 糕 的 程 序 设 计 风 格 。
有 关 指 针 的 更 多 的 信 息 参 见 本 章 后 面 的 “ 派 生 类 ”。 有 关 类 对 象 的 说 明 和 初 始 化详 见 第 8 章 “ 类 ”。 有 关 使 用 new 和 delete 自 由 存 储 运 算 符 的 更 多 信 息 , 参 见 第11 章 “ 特 殊 的 成 员 函 数 ”。
函 数 的 形 式 参 量 的 范 围
函 数 的 形 式 参 量 ( 在 函 数 定 义 内 指 定 的 参 量 ) 被 认 为 是 在 函 数 体 的 最 外 层 块 的 范围 内 。
程 序 和 连 接
- 个 程 序 由 连 接 在 一 起 的 一 个 或 多 个 转 换 单 元 组 成 , 从 包 含 main 函 数 的 转 换 单元 开 始 执 行 ( 概 念 上 )( 有 关 转 换 单 元 的 更 多 信 息 , 参 见 本 书 后 面 “ 预 处 理 器 参 考 ” 的 “ 翻 译 阶 段 ”。
有 关 main 函 数 , 详 见 本 章 后 面 的 “ 程 序 开 始 :main 函 数 ” ) 。
连 接 的 类 型
在 转 换 单 元 之 间 共 享 对 象 或 函 数 的 名 称 的 方 式 被 称 为 “ 连 接 ”。 这 些 名 称 有 :
- 内 部 连 接 , 即 它 们 仅 指 自 己 的 转 换 单 元 中 的 程 序 元 素 , 不 与 其 它 转 换单 元 共 享 。
在 其 它 转 换 单 元 中 的 相 同 的 名 称 可 以 指 不 同 的 对 象 或 不 同 的 类 。 具 有 内 部 连 接的 名 称 有 时 被 认 为 相 对 于 它 们 的 转 换 单 元 是 局 部 的 。
具 有 内 部 连 接 的 名 称 的 一 个 说 明 例 子 如 下 :
static int i //static 关 键 字 确 保 是 内 部 连 接
- 外 部 连 接 , 即 指 程 序 中 的 任 意 一 个 转 换 单 元 中 的 程 序 元 素 , 在 转 换 单元 的 之 间 共 享 。
在 另 一 个 转 换 单 元 中 的 相 同 名 称 被 认 定 为 指 示 同 一 个 对 象 或 类 , 具有 外 部 连 接 的 名 称 有 时 被 认 为 是 全 局 的 。
具 有 外 部 连 接 的 名 称 的 一 个 说 明 例 子 如 下 : extern int i;
- 无 连 接 , 即 指 唯 一 实 体 , 在 另 一 个 范 围 中 的 同 样 的 名 称 可 能 不 是 相 同的 对 象 , 例 如 一 个 枚 举 ( 但 注 意 , 你 可 以 用 无 连 接 来 向 一 个 对 象 传 递一 个 指 针 , 这 使 得 在 其 它 转 换 单 元 中 该 对 象 是 可 访 问 的 。 )
具 有 文 件 范 围 的 名 称 的 连 接
以 下 的 连 接 规 则 适 用 于 具 有 文 件 范 围 的 名 称 ( 不 是 typedef 及 枚 举 器 名 称 ):
- 如 果 一 个 名 称 被 显 式 说 明 为 static, 则 它 具 有 内 部 连 接 , 标 识 在 转 换
单 元 内 的 一 个 程 序 元 素 。
-
枚 举 器 名 称 及 typedef 名 称 是 无 连 接
-
具 有 文 件 范 围 的 所 有 其 它 的 名 称 都 是 外 部 连 接
Microsoft 特 殊 处 →
- 如 果 一 个 具 有 文 件 范 围 的 函 数 名 称 被 显 式 说 明 为 inline, 如 果 它 被实 例 化 或 其 地 址 被 引 用 时 , 它 具 有 外 部 连 接 。 因 此 , 对 于 一 个 具 有 文件 范 围 的 函 数 , 可 能 有 内 部 或 外 部 的 连 接 。
Microsoft 特 殊 处 结 束
-
个 类 有 内 部 连 接 , 如 果 :
-
不 使 用 C++ 功 能 ( 例 如 成 员 访 问 控 制 、 成 员 函 数 、 构 造 函 数 、 析 构 函数 等 )
-
不 用 于 说 明 具 有 外 部 连 接 的 另 一 个 名 称 。 此 限 制 意 味 着 , 类 类 型 对象 传 递 给 具 有 外 部 连 接 的 函 数 导 致 类 具 有 外 部 连 接 。
-
具 有 类 范 围 的 名 称 的 连 接
以 下 连 接 规 则 适 用 于 具 有 类 范 围 的 名 称 :
-
静 态 类 成 员 具 有 外 部 连 接
-
类 成 员 函 数 具 有 外 部 连 接
-
枚 举 器 及 typedef 名 称 是 无 连 接
Microsoft 特 殊 处 →
- 被 说 明 为 friend 函 数 的 函 数 必 须 具 有 外 部 连 接 。 把 一 个 静 态 函 数说 明 为 friend 会 出 错 。
Microsoft 特 殊 处 结 束
具 有 块 范 围 的 名 称 的 连 接
以 下 连 接 规 则 适 用 于 具 有 块 范 围 的 名 称 ( 局 部 名 称 ):
-
说 明 为 extern 的 名 称 具 有 外 部 连 接 , 除 非 它 们 在 前 面 说 明 为 static
-
具 有 块 范 围 的 所 有 其 它 名 称 是 无 连 接
具 有 无 连 接 的 名 称
具 有 无 连 接 的 名 称 仅 仅 有 :
-
函 数 参 量
-
没 有 被 说 明 为 extern 或 static 的 块 范 围 名 称
-
枚 举 器
-
在 typedef 语 句 中 说 明 的 名 称 , 而 当 typedef 语 句 用 于 为 一 个 未 命名 的 类 类 型 提 供 一 个 名 称 时 是 一 个 例 外 。 如 果 类 具 有 外 部 连 接 , 则该 名 称 可 能 具 有 外 部 连 接 。以 下 例 子 给 出 了 具 有 外 部 连 接 的 typedef 名 称 的 情 形 :
typedef struct
{
short x;
short y;
} POINT
extern int MoveTo(POINT pt);
typedef 名 称 POINT 成 了 未 命 名 的 结 构 的 类 名 , 然 后 它 被 用 于 说 明 一 个 具 有 外 部连 接 的 函 数 。
因 为 typedef 名 称 为 无 连 接 , 所 以 在 转 换 单 元 之 间 它 们 的 定 义 可 以 不 同 , 因 为 编译 是 独 立 地 进 行 的 , 所 以 编 译 器 无 法 检 查 出 这 些 不 同 处 , 结 果 是 , 这 种 类 型 的 错 误要 到 链 接 时 才 能 被 查 出 。
考 虑 以 下 情 形 :
// 转 换 单 元 1 typedef int INT
INT myInt;
...
// 转 换 单 元 2 typedef short INT
extern INT myInt
...
前 面 的 代 码 在 链 接 时 产 生 一 个 “ 未 分 解 的 外 部 ” 错 误 。
C++ 函 数 仅 能 在 文 件 或 类 范 围 内 定 义 , 以 下 例 子 描 述 了 如 何 定 义 函 数 并 给 出 了 一个 错 误 的 函 数 定 义 :
#include <iostream.h>
void ShowChar(char ch); // 说 明 函 数 ShowChar
void ShowChar(chat ch) // 定 义 函 数 ShowChar
{ // 函 数 具 有 文 件 范 围
cout << ch;
}
struct Char // 定 义 类 Char
{
char Show(); // 说 明 Show 函 数
char Get(); // 说 明 Get 函 数
char ch;
};
char Char::Show() // 定 义 具 有 类 范 围 的 Show 函 数
{
cout << ch;
return ch
}
void GoodFuncDef(char ch) // 定 义 具 有 文 件 范 围 的 GoodFuncDef
{
int BadFuncDef(int i) // 错 误 地 嵌 套 函 数
{
return i * 7;
}
for (int i = 0;i < BadFuncDef(2); ++i)
cout << ch;
cout << "\ n" ;
}
连 接 到 非 C++ 函 数 :
只 有 在 前 面 说 明 为 具 有 C 连 接 的 C 函 数 和 数 据 才 能 被 访 问 。 可 是 , 它 们 必 须 定 义在 分 开 的 编 译 过 的 转 换 单 元 中 。
语 法
连 接 规 格 :
extern 字 符 串 文 字 { 说 明 表 opt }
extern 字 符 串 文 字 说 明说 明 表 :
说 明
说 明 表 说 明
Microsoft C++ 支 持 字 符 串 文 字 域 中 的 字 符 串 “ C ” 和 “ C++ ”。 以 下 例 子 给 出 了可 选 择 的 具 有 C 连 接 的 名 称 的 说 明 方 法 :
// 说 明 printf 具 有 C 连接
extern "C" int printf (const char *fmt,...);
// 使 头 文 件 "cinclude.h 中 的 所 有 内 容 具 有 C 连 接extern "C"
{
#include <cinclude.h>
}
// 说 明 具 有 C 连 接 的 两 个 函 数 ShowChar 和 GetChar extern "C"
{
char ShowChar(char ch); char GetChar(void);
}
// 定 义 具 有 C 连 接 的 两 个 函 数 ShowChar 和 GetChar extern "C" char ShowChar(char ch)
{
putchar(ch);
return ch;
}
extern "C" char GetChar(void)
{
char ch;
ch = getchar();
return ch
}
// 说 明 一 个 具 有 C 连 接 的 全 局 变 量 errno extern "C" int errno;
启 动 和 结 束
通 过 使 用 两 个 函 数 :main 和 exit, 使 程 序 方 便 地 启 动 和 结 束 。 其 它 的 启 动 和 结 束代 码 可 能 被 执 行 。
程 序 启 动 :main 函 数
- 个 被 称 为 main 的 特 殊 函 数 是 所 有 C++ 程 序 的 入 口 点 , 此 函 数 并 未 被 编 译 器 预定 义 , 而 是 必 须 在 程 序 文 本 中 提 供 。 如 果 你 正 在 编 写 依 附 于 单 代 码 程 序 设 计 模 式的 代 码 , 你 可 以 使 用 main 的 宽 字 符 版 本 wmain 。 main 的 说 明 语 法 是 :
int main(); 或 , 可 选 地 :
int main(int argc [,char * argv [] [,char* envp []]]); wmain 的 说 明 语 法 如 下 :
int wmain(); 或 , 可 选 地 :
int wmain(int argc [,wchar_t * argv [][,wchar_t * envp []]]);
另 外 ,main 和 wmain 函 数 还 可 被 说 明 为 返 回 值 是 void( 无 返 回 值 ) 。如 要 你 将 main 或 wmain 说 明 为 返 回 值 void, 则用 return 语 句 无 法 向 父 进 程 或 操 作 系 统 返 回 退出 代 码 。当 main 或 wmain 被 说 明 为 void 时 , 若 要 返 回 退 出 代 码 , 则 必 须 使 用 exit 函 数 。
使 用 wmain 代 替 main
在 单 代 码 程 序 设 计 模 式 中 , 你 可 以 定 义 main 函 数 的 宽 字 符 版 本 。 如 果 你 想 编 写可 移 植 的 依 附 于 单 代 码 规 格 的 代 码 , 则 使 用 wmain 代 替 main 。
你 用 与 main 相 似 的 格 式 说 明 wmain 的 形 式 参 量 , 而 后 你 可 以 向 程 序 传 递 宽 字 符参 量 及 可 选 地 宽 字 符 环 境 指 针 。 wmain 的 argv 和 envp 参 量 是 wchar_t * 类 型 。如 果 你 的 程 序 使 用 main 函 数 , 则 在 程 序 开 始 处 由 操 作 系 统 创 建 了 一 个 多 字 节 字符 环 境 , 环 境 的 一 个 宽 字 符 拷 贝 仅 在 需 要 时 创 建 。 ( 例 如 , 通 过 对 _wgetenv 或
_wputenv 函 数 的 调 用 ) 。 在 第 一 次 调 用 _wputenv 或 第 一 次 调 用 _wgetenv 时 , 如果 已 经 存 在 MBCS 环 境 , 则 一 个 相 应 的 宽 字 符 字 符 串 环 境 被 创 建 , 且 由 一 个
_wenviron 全 局 变 量 指 向 , 它 是 _environ 全 局 变 量 的 宽 字 符 版 本 。 在 这 点 上 , 环
境 的 两 份 拷 贝 (MBCS 和 单 代 码 ) 同 时 存 在 , 且 在 程 序 的 整 个 生 存 期 中 由 操 作 系 统获 得 。
同 样 地 , 如 果 你 的 程 序 使 用 wmain 函 数 , 则 在 第 一 次 调 用 _putenv 或 getenv 时 创建 一 个 MBCS(ASCII) 环境 , 且 由 全 局 变 量 _environ 指 向 。
有 关 MBCS 环 境 的 更 多 信 息 , 参 见 “ Microsoft Visual C++ 6.0 参 考 库 ” 的“ Microsoft Visual C++ 6.0 运 行 库 参 考 ” 中 的 第 2 章 “ 单 字 节 和 多 字 节 字 符集 ” 。
在 原 型 :
参 量 变 义
int main(int argc [,char * argv [][,char * envp []]]); 或
int wmain(int argc [,wchar_t * argv [][,wchart_t * envp []]]);
中 的 参 量 允 许 进 行 方 便 的 参 量 命 令 行 语 法 分 析 , 且 可 选 择 地 访 问 环 境 变 量 。 参 量定 义 如 下 :
argc
包 含 跟 随 在 argv 后 面 的 参 量 个 数 的 整 数 。 argc 参 量 总 是 大 于 或 等 于 1 。
argv
是 一 个 以 空 格 结 尾 字 符 串 的 数 组 , 表 示 由 程 序 的 用 户 在 命 令 行 输 入 的 参 量 。 通 过转 换 , argv [0] 是 调 用 程 序 的 命 令 ,argv[1] 是 第 一 个 命 令 行 参 量 , 如 此 等 等 , 直 到argv[ argc ], 它 总 是 为 NULL 。有 关 截 取 命 令 行 处 理 的 更 多 信 息 , 参 见 本 章 后 面“ 定制 C++ 命 令 行 处 理 ”。
第 一 个 命 令 行 参 量 总 是 argv[1], 而 最 后 一 个 是 argv [argc-1] 。
Microsoft 特 殊 处 →
envp
envp 数 组 用 于 Microsoft C++ 中 , 它 也 是 很 多 UNIX 系 统 的 常 见 的 扩 充 。 它 是 一个 字 符 串 数 组 , 用 于 表 示 在 用 户 环 境 设 置 的 变 量 , 此 数 组 由 一 个 NULL 项 结 尾 。 关于 截 取 环 境 处 理 的 信 息 , 参 见 本 章 后 面 的 “ 定 制 C++ 命 令 行 处 理 ”。 该 参 量 在 C 中 是 ANSI 兼 容 的 , 但 在 C++ 中 却 不 是 。
Microsoft 特 殊 处 结 束
以 下 例 子 展 示 如 何 使 用 main 中 的 argc 、 argv 和 envp 参量 : #include <iostream.h>
#include <string.h>
void main(int argc, char *argv[], char *envp[])
{
int iNumberLines = 0; // 缺 省 情 况 是 没 有 行 号
// 如 果 不 只 提 供 了 .EXE 文 件 名 , 而 且 指 定 了 命 令 行 选 项 /n
// 则 环 境 变 量 的 列 表 是 按 行 编 号 的
if (argc==2 && srticmp(argv [1],"/n")==0)
iNumberLines=1;
// 通 过 字 符 串 表 直 到 遇 到 NULL
for (int i=0; envp[i]!=NULL;++i)
{
if (iNumberLines)
cout << i << ": "<< envp[i]<<"\n"
}
}
通 配 符 扩 展
Microsoft 特 殊 处 →
你 可 以 在 命 令 行 使 用 通 配 符 问 号 (?) 和 星 号 (*), 指 定 文 件 名 和 路 径 变 量 。 命 令 行参 量 由 被 称 为 _setargv 的 例 行 程 序 处 理 。 缺 省 地 ,_setargv 将 通 配 符 扩 展 为 单独 字 符 串 进 入 argv 字 符 串 数 组 中 , 如 果 通 配 符 变 量 未 找 到 匹 配 , 则 参 量 作 为 文 字传 送 。
Microsoft 特 殊 处 结 束
分 析 C++ 命 令 行 变 量
Microsoft 特 殊 处 →
Microsoft C/C++ 开 始 代 码 使 用 以 下 规 则 解 释 操 作 系 统 命 令 行 给 出 的 参 量 :
-
参 量 由 空 白 定 界 , 可 以 是 一 个 空 格 或 一 个 制 表 符
-
插 入 字 符 (^) 不 被 认 为 是 一 个 转 义 字 符 或 定 界 符 。 在 传 递 给 程 序 中的 argv 数 组 前 , 字 符 由 操 作 系 统 中 命 令 行 语 法 分 析 程 序 进 行 完 全 处理 。
-
由 双 引 号 包 围 的 字 符 串 ( “ 字 符 串 ” ) 被 解 释 为 单 个 参 量 , 而 不 管 其中 是 否 包 含 空 白 。 被 引 号 括 起 的 字 符 串 可 以 嵌 入 参 量 中 。
-
由 反 斜 杠 引 导 的 一 个 双 引 号 (\") 被 解 释 为 一 个 文 字 双 引 号 字 符 (")
-
反 斜 杠 被 作 为 文 字 解 释 , 除 非 它 们 后 面 紧 跟 一 个 双 引 号 。
-
如 果 偶 数 个 反 斜 杠 后 面 跟 随 一 个 双 引 号 , 则 为 每 对 反 斜 杠 放 一 个 反斜 杠 到 argv 数 组 中 , 双 引 号 被 解 释 为 一 个 字 符 串 定 界 符 。
-
如 果 奇 数 个 反 斜 杠 后 面 跟 随 一 个 双 引 号 , 为 每 对 反 斜 杠 放 一 个 反 斜杠 到 argv 数 组 中 , 双 引 号 则 被 剩 下 的 反 斜 杠 进 行 “ 转 义 ” 而 使 得 一个 文 字 双 引 号 (") 放 入 到 argv 中 。
以 下 例 子 说 明 命 令 行 参 量 是 如 何 被 传 递 的 : include <iostream.h>
void main(int argc, // 数 组 argv 中 的 字 符 串 个 数
char *argv[], // 命 令 行 参 量 字 符 串 数 组
char *envp[] )// 环 境 变 量 字 符 串 数 组
{
int count;
// 显 示 每 个 命 令 行 参 量
cout << "\nCommand-line arguments:\n";
for ( count = 0;count < argc;count++)
cout << " argv["<<count<<"] "
<< argv[count]<< "\n";
}
表 2.2 给 出 例 子 输 入 和 预 期 的 输 出 以 说 明 前 面 列 出 的 规 则 。
表 2.2 语 法 分 析 命 令 行 的 结 果
命令行输入 |
argv[1] |
argv[2] |
argv[3] |
---|---|---|---|
"abc"d e |
abc |
d |
e |
a\\\b d"e f"g h |
a\\\b |
de fg |
h |
a\\\"b c d |
a\"b |
c |
d |
a\\\"b c" d e |
a\\b c |
d |
e |
Microsoft 特 殊 处 结 束
定 制 C++ 命 令 行 处 理
Microsoft 特 殊 处 →
如 果 你 的 程 序 不 采 用 命 令 行 参 量 , 你 可 以 通 过 截 取 执 行 命 令 行 处 理 的 库 例 行 程 序的 使 用 而 节 省 一 小 部 分 空 间 。 这 个 例 行 程 序 被 称 为 _setargv 且 在 “ 通 配 符 扩 展 ” 中 描 述 。 为 了 截 取 它 的 使 用 , 在 包 含 main 函 数 的 文 件 中 定 义 一 个 例 程 , 什 么 也 不做 , 但 要 命 名 为 _setargv; 然 后 对 _setargv 的 调 用 将 被 你 定 义 的 _setargv 去 满 足 , 则 没 有 加 载 其 库 版 本 。
类 似 地 , 如 果 你 从 未 通 过 envp 参 量 访 问 环 境 表 , 但 可 以 提 供 你 自 己 的 空 例 程 取 代环 境 处 理 例 程 _setenvp 。就 如 同 使 用 _setargv 函 数 ,_setenvp 必 须 说 明 为 extern “ C ”。
你 的 程 序 可 能 调 用 C 运 行 时 库 中 的 spawn 或 exec 例 程 簇 。 如 果 是 这 种 情 况 , 你不 能 取 消 环 境 处 理 例 程 , 因 为 这 个 例 程 用 于 从 父 进 程 向 子 进 程 传 递 一 个 环 境 。Microsoft 特 殊 处 结 束
main 函 数 限 制
main 函 数 有 几 条 限 制 不 适 用 任 何 其 它 的 C++ 函 数 。 main 函 数 :
-
不 能 重 载 ( 参 见 第 12 章 “ 重 载 ” )
-
不 能 说 明 为 inline
-
不 能 说 明 为 static
-
不 能 取 其 地 址
-
不 能 被 调 用
程 序 结 束
在 C++ 中 , 有 几 种 方 式 退 出 程 序 ;
-
调 用 exit 函 数
-
调 用 abort 函 数
-
从 main 执 行 一 条 return 语句
exit 函 数
在 标 准 包 括 文 件 STDLIB.H 中 说 明 的 exit 函 数 用 于 终 止 一 个 C++ 程 序 。
提 供 作 为 exit 一 个 参 量 的 值 将 作 为 程 序 返 回 码 或 退 出 码 返 回 给 操 作 系 统 。 通 过约 定 ,0 返 回 码 意 味 着 程 序 成 功 地 完 成 了 。
注 意 : 你 可 以 使 用 定 义 在 STDLIB.H 中 的 常 量 EXIT_FAILURE 和 EXIT_SUCCESS 来指 示 你 的 程 序 的 成 功 或 失 败 。
从 main 函 数 发 出 一 个 return 语 句 等 价 于 用 其 返 回 值 作 参 量 去 调 用 exit 函 数 。有 关 更 多 的 信 息 参 见 “ Microsoft Visual C++ 6.0 运 行 库 参 考 ” 中 的 “ exit ”。
abort 函 数
也 在 标 准 包 括 文 件 STDLIB.H 中 说 明 的 abort 函 数 用 于 终 止 一 个 C++ 程 序 。 exit 和 abort 之 间 的 区 别 是 :exit 允 许 C++ 发 生 运 行 终 止 处 理 ( 调 用 全 局 变 量 析 构 函数 ), 而 abort 则 是 立 即 终 止 程 序 。 有 关 更 多 的 信 息 参 见 “ Microsoft Visual C++6.0 运 行 库 参 考 ” 中 的 “ abort ”。
return 语 句
从 main 发 出 一 条 return 语 句 在 功 能 上 等 价 于 调 用 exit 函 数 。 考 虑 以 下 例 子 : int main
{
exit (3);
return 3;
}
在 上 例 中 exit 和 return 语 句 功 能 上 是 完 全 相 同 的 , 可 是 C++ 要 求 在 返 回 一 个 数值 时 函 数 应 有 返 回 类 型 而 不 是 void 。 return 语 句 允 许 从 main 返 回 一 个 值 。
额 外 的 启 动 考 虑
在 C++ 中 , 对 象 的 构 造 函 数 和 析 构 函 数 可 以 包 含 执 行 用 户 代 码 , 因 此 , 了 解 进 入main 之 前 发 生 了 什 么 初 始 化 以 及 从 main 退 出 以 后 什 么 析 构 函 数 被 调 用 是 很 重要 的 ( 有 关 对 象 的 构 造 函 数 和 析 构 函 数 , 参 见 第 11 章 “ 特 殊 成 员 函 数 ” 中 的 “ 构造 函 数 ” 和 “ 析 构 函 数 ” ) 在 进 入 main 之 前 发 生 了 以 下 初 始 化 :
-
静 态 数 据 缺 省 初 始 化 为 0 。 没 有 明 确 初 始 化 的 所 有 静 态 数 据 在 执 行任 何 其 它 代 码 包 括 运 行 初 始 化 前 均 被 设 定 为 0 。 静 态 数 据 成 员 还 必须 加 以 显 式 地 定 义 。
-
在 一 个 转 换 单 元 中 的 全 局 静 态 对 象 的 初 始 化 。 它 的 发 生 可 能 出 现 在进 入 main 之 前 或 在 对 象 的 转 换 单 元 中 的 任 何 函 数 或 对 象 的 第 一 次使 用 之 前 。
Microsoft 特 殊 处 →
在 Microsoft C++ 中 , 全 局 静 态 对 象 在 进 入 main 之 前 初 始 化 。
Microsoft 特 殊 处 结 束
全 局 静 态 对 象 是 彼 此 相 互 依 赖 的 , 但 在 不 同 的 转 换 单 元 中 可 能 产 生 不 正 确 的 动作 。
额 外 的 终 止 考 虑
你 可 以 用 exit 、 return 或 abort 终 止 一 个 C++ 程 序 。 可 以 使 用 atexit 函 数 增加 退 出 处 理 , 这 些 在 下 节 中 讨 论 。
使 用 exit 或 return
当 你 从 main 中 调 用 exit 或 执 行 一 条 return 语 句 时 , 静 态 对 象 按 照 与 初 始 化 相反 的 顺 序 被 销 毁 , 下 面 的 例 子 显 示 了 如 何 初 始 化 和 清 除 工 作 的 :
#include <stdio.h> class ShowData
{
public:
// 构 造 函 数 打 开 一 个 文 件
ShowData(const char *szDev)
{
OutputDev=fopen(szDev,"w");
}
// 析 构 函 数 关 闭 一 个 文 件
~ShowData() { fclose(OutputDev); }
//Disp 函 数 在 输 出 设 备 上 显 示 一 字 符 串
void Disp(char *szData)
{
fputs(szData,OutputDev);
}
private:
FILE *OutputDev;
};
// 定 义 一 个 类 型 为 ShowData 的 静 态 对 象 , 选 取 的 输 出 设 备 是 "CON" 即 标 准 输 出 设备
ShowData sdl="CON";
// 定 义 另 一 个 类 型 为 ShowData 的 静 态 对 象 , 直 接 输 出 到 文 件 "HELLO.DAT" 中ShowData sd2="CON",
int main()
{
sd1 Disp("hello to default device\n");
s d 2.Disp("hello to file hello.dat\n");
return 0;
}
在 上 面 的 例 子 中 , 静 态 对 象 sd1 和 sd2 在 进 入 main 之 前 被 创 建 并 被 初 始 化 , 在 使用 return 语 句 终 止 该 程 序 后 , 先 销 毁 sd2 而 后 是 sd1 。 ShowData 类 的 析 构 函 数关 闭 这 些 静 态 对 象 相 关 的 文 件 ( 有 关 初 始 化 、 构 造 函 数 、 析 构 函 数 的 更 多 信 息 , 参 见 第 11 章 “ 特 殊 成 员 函 数 ” ) 。
编 写 这 个 代 码 的 另 一 种 方 法 是 说 明 为 块 范 围 对 象 ShowData, 且 允 许 它 们 在 超 出
范 围 时 被 销 毁 :
int main()
{
ShowData sd1,sd2("hello.dat");
sd1.Disp("hello to default device\n");
sd2.Disp("hello to file hello.dat\n");
return 0;
}
使 用 atexit
使 用 atexit 函 数 , 你 可 以 指 定 一 个 退 出 处 理 函 数 在 程 序 终 止 前 执 行 。 没 有 一 个在 atexit 调 用 之 前 初 始 化 的 全 局 静 态 对 象 在 退 出 该 处 理 函 数 执 行 前 被 销 毁 的 。
使 用 abort
调 用 abort 函 数 立 即 引 起 终 止 , 它 越 过 初 始 化 的 全 局 静 态 对 象 的 正 常 的 析 构 过 程 , 还 越 过 了 使 用 atexit 函 数 指 定 的 任 何 特 殊 处 理 。
存 储 类
存 储 类 管 理 C++ 中 的 对 象 和 变 量 的 生 存 期 、 连 接 和 处 理 。 一 个 给 定 的 对 象 只 能
有 一 个 存 储 类 。 本 节 讨 论 数 据 的 C++ 存 储 类 :
-
自 动 的
-
静 态 的
-
寄 存 器 的
-
外 部 的
自 动 的
自 动 存 储 的 对 象 和 变 量 对 于 一 个 块 的 给 定 实 例 是 局 部 的 。 在 递 归 或 多 线 程 代 码中 , 自 动 对 象 和 变 量 被 保 证 为 在 一 个 块 的 不 同 实 例 中 有 不 同 的 存 储 。 Microsoft C++ 在 程 序 的 栈 中 存 储 自 动 的 对 象 和 变 量 。
在 一 个 块 内 定 义 的 对 象 和 变 量 为 auto 存 储 , 除 非 用 extern 或 static 关 键 字 加以 指 定 。 自 动 的 对 象 和 变 量 可 以 用 auto 关 键 字 加 以 指 定 , 但 没 有 必 要 显 式 指 明auto 。 自 动 的 对 象 和 变 量 是 无 连 接 的 。
自 动 的 对 象 和 变 量 仅 仅 持 续 到 它 们 被 说 明 的 所 在 块 的 结 束 。
静 态 的
被 说 明 为 static 的 对 象 和 变 量 在 程 序 执 行 期 间 保 留 它 们 的 值 。 在 递 归 代 码 中 , 一 个 静 态 对 象 或 变 量 在 一 个 块 代 码 的 不 同 实 例 中 确 保 有 相 同 的 状 态 。
在 所 有 块 的 外 部 定 义 的 对 象 和 变 量 缺 省 地 具 有 静 态 生 存 期 和 外 部 连 接 。 被 显 式地 说 明 为 static 的 一 个 全 局 对 象 或 变 量 具 有 内 部 连 接 。
静 态 对 象 和 变 量 在 程 序 执 行 的 期 间 是 持 续 的 。
寄 存 器 的
只 有 函 数 的 参 量 和 局 部 变 量 可 以 说 明 为 寄 存 器 存 储 类 。
象 自 动 变 量 一 样 , 寄 存 器 的 变 量 仅 仅 持 续 到 它 们 被 说 明 的 所 在 块 的 结 束 。
编 译 器 不 允 准 用 户 对 寄 存 器 变 量 的 要 求 , 相 反 地 , 当 全 局 优 化 在 使 用 时 , 编 译 器 作出 自 己 的 寄 存 器 选 择 , 可 是 , 编 译 器 允 准 所 有 register 关 键 字 的 相 关 语 义 。
外 部 的
被 说 明 为 extern 的 对 象 和 变 量 说 明 一 个 定 义 在 另 一 个 转 换 单 元 中 的 对 象 或 一 个具 有 外 部 连 接 的 封 闭 的 范 围 中 的 对 象 。
具 有 extern 存 储 类 的 const 变 量 的 说 明 强 制 变 量 具 有 外 部 连 接 , 一 个 extern const 变 量 的 初 始 化 允 许 定 义 在 转 换 单 元 中 。 在 一 个 转 换 单 元 中 初 始 化 而 不 是定 义 在 该 转 换 单 元 中 , 这 将 产 生 不 确 定 的 结 果 。
以 下 例 子 给 出 了 两 个 extern 说 明 :DefinedElsewhere( 指 向 定 义 在 一 个 不 同 的 转换 单 元 中 的 名 称 ) 和 DefinedHere( 指 向 定 义 在 一 个 封 闭 的 范 围 中 的 名 称 ): extern int DefinedElsewhere;// 定 义 在 另 一 个 转 换 单 元 中
void main()
{
int DefinedHere;
{
extern int DefinedHere;// 指 向 封 闭 的 范 围 中 的 DefinedHere
}
}
对 象 的 初 始 化
- 个 局 部 的 自 动 的 对 象 或 变 量 在 控 制 流 程 每 次 到 达 它 的 定 义 时 都 被 初 始 化 。 一个 局 部 的 静 态 对 象 或 变 量 在 控 制 流 程 第 一 次 到 达 它 的 定 义 时 被 初 始 化 。 考 虑 以下 例 子 , 例 子 中 定 义 了 一 个 类 , 它 历 经 对 象 的 初 始 化 和 析 构 , 而 后 定 义 了 三 个 对 象I1 、 I2 和 I3:
#include <iostream.h> #include <string.h>
// 定义了一个类 , 它历经初始化和析构class InitDemo
{
public:
InitDemo(const char *szWhat);
~InitDemo(); private:
char *szObjName;
};
// 类 InitDemo 的析构函数
InitDemo::InitDemo (const char * szWhat)
{
if ( szWhat!=0 && strlen(szWhat)>0 )
{
// 为 szObjName 分配存储 , 然后将 szWhat 初始值拷贝到 szObjName
szObjName=new char[strlen(szWhat)+1];
strcpy (szObjName,szWhat);
cout << "Initializing" << szObjNmae << "\n";
}
else
szObjName=0;
}
//InitDemo 的析构函数InitDemo::~InitDemo()
{
if (szObjName!=0)
{
cout << "Destroying: " << szObjName << "\n";
delete szObjName;
}
}
// 输入 main 函数void main()
{
InitDemo I1("Auto I1")
{
cout << "In block.\n";
InitDemo I2("Auto I2");
static InitDemo I3("Static I3");
}
cout << "Exited block.\n";
}
上 面 的 代 码 描 述 了 对 象 I1 、 I2 和 I3 是 如 何 以 及 何 时 被 初 始 化 的 和 何 时 被 销 毁的 。 该 程 序 的 输 出 为 :
Initializing: Auto I1 In block.
Initializing: Auto I2 Initializing: Static I3 Destroying: Auto I2 Exited block.
Destroying: Auto I1 Destrying: Static I3
关 于 程 序 有 几 点 要 注 意 的 :
第 一 ,I1 和 I2 在 控 制 流 退 出 定 义 它 们 的 块 时 被 自 动 销 毁 。
第 二 , 在 C++ 中 , 没 有 必 要 在 一 个 块 的 开 始 去 说 明 对 象 或 变 量 。 此 外 , 这 些 对 象 仅当 控 制 流 到 达 它 们 的 定 义 时 才 被 初 始 化 (I2 和 I3 是 这 种 定 义 的 例 子 ), 输 出 确 切地 显 示 了 他 们 是 何 时 被 初 始 化 的 。
最 后 , 静 态 局 部 变 量 例 如 I3 在 程 序 的 持 续 期 间 保 留 它 们 的 值 , 但 是 在 程 序 结 束 时被 销 毁 。
类 型
C++ 支 持 三 种 对 象 类 型 :
-
基 本 类 型 是 建 立 在 语 言 中 的 ( 如 int 、 float 或 double) 。 这 些 基 本类 型 的 实 例 通 常 被 称 为 “ 变 量 ”。
-
派 生 类 是 从 内 部 类 型 派 生 的 新 类 型 。
-
类 类 型 是 通 过 现 存 类 型 组 合 创 建 的 新 类 型 , 这 些 在 第 8 章 “ 类 ” 中讨 论 。
基 本 类 型
C++ 中 的 基 本 类 型 分 为 三 类 : “ 整 型 的 ”、“ 浮 点 ” 和 “ void ”。 整 型 能 够 处 理 全 部的 数 ; 浮 点 类 型 能 够 指 定 可 能 有 小 数 部 分 的 值 。
void 类 型 描 述 值 的 空 集 。 不 能 指 定 void 类 型 的 变 量 , 它 基 本 上 用 于 说 明 没 有 返
回 值 的 函 数 或 说 明 无 类 型 或 任 意 类 型 的 数 据 的 “ 通 用 ” 指 针 。 任 何 表 达 式 可 显式 地 转 换 或 造 型 转 换 为 类 型 void, 可 是 , 这 些 表 达 式 限 于 以 下 应 用 :
-
一 个 表 达 式 语 句 ( 参 见 第 4 章 “ 表 达 式 ” ) 。
-
逗 号 运 算 符 的 左 侧 操 作 数 ( 参 见 第 4 章 “ 表 达 式 ” 中 的 “ 逗 号 运 算符 ” ) 。
-
条 件 运 算 符 的 (?:) 的 第 二 或 第 三 个 操 作 数 ( 参 见 第 4 章 “ 表 达 式 ” 中 的 “ 带 条 件 运 算 符 的 表 达 式 ” ) 。
表 2.3 解 释 了 类 型 尺 寸 的 限 制 , 这 些 限 制 是 独 立 于 Microsoft 实 现 的 。
表 2.3 |
C++ 语 言 的 基 本 类 型 |
|
---|---|---|
目录 |
类型 |
内容 |
整型 |
char |
类型 char 是整型 , 通常包含执行字符集的成员, |
在 Microsoft C++ 中 , 这是 ASCII 码 |
||
C++ 编 译 器 把 类 型 为 char 、 signed char 和 |
unsigned char 的 变 量 作 为 具 有 不 同 的 类 型 对待。类型为 char 的变量被提升为 int, 就好象它们缺省为 signed char, 除非使用 /J 编译选项。在这种情况下 , 它 们 被 作 为 类 型 unsigned char, 且被提升为不带符号扩展的 int
short 类型 short int( 或 简 称 short) 是 一 个 整 型 , 大
于或等于 char 类型的尺寸 , 小于或等于 int 类型的尺寸
short 类型的对象可被说明为 signed short 或
unsigned short
signed short 是 short 的同义词
int 类型 int 是整型 , 它大于或等于 short int 类型的尺寸 , 小于或等于类型 long 的尺寸
int 类 型 的 对 象 可 被 说 明 为 signed int 或unsigned int 。 signed int 是 int 的同义词
续 表
__in tn 指定整型变量的尺寸 , 这里的 n 是以位为单位给出的尺寸 ,n 的值可 以是 8 、 16 、 32 或 64
long 类型 long( 或 long int) 是大于或等于类型 int 的尺寸的整型
long 类 型 的 对 象 可 被 说 明 为 signed long 或unsigned long
signed long 是 long 的同义词浮点 float 类型 float 是最小的浮点类型
double 类 型 double 是 一 个 浮 点 类 型 , 它 大 于 或 等 于
float 类 型 的 尺 寸 , 但 小 于 或 等 于 long double 类型的尺寸
long double * 类型 long double 是一个等于类型 double 的浮
点类型
*long double 和 double 的 表 示 是 完 全 相 同 的 , 可是 long double 和 double 是两 种 类 型 。
Microsoft 特 殊 处 →
表 2.4 列 出 了 Microsoft C++ 中 基 本 类 型 所 需 的 存 储 空 间 大 小 。
表 2.4 基 本 类 型 的 尺 寸
类型 尺寸
char,unsigned char,signed char |
1 |
个字节 |
---|---|---|
short,unsigned short |
2 |
个字节 |
int,unsigned int |
4 |
个字节 |
long,unsigned long |
4 |
个字节 |
float |
4 |
个字节 |
double |
8 |
个字节 |
long double * |
8 |
个字节 |
*long double 和 double 的 表 示 是 完 全 相 同 的 , 但 long double 和 double 是 两种 类 型 。
关 于 类 型 转 换 的 更 多 信 息 , 参 见 第 3 章 “ 标 准 转 换 ”。
Microsoft 特 殊 处 结 束指 定 尺 寸 的 整 型
Microsoft C++ 还 支 持 指 定 尺 寸 的 整 型 , 你 可 以 使 用 __ int n 类 型 指 示 符 来 说 明 8 、16 、 32 或 64 位 的 整 数 变 量 , 其中 n 是 整 型 变 量 的 尺 寸 , n 值 可 为 8 , 16 , 32 , 或
64 。 以 下 例 子 为 每 个 这 些 指 定 尺 寸 的 整 型 数 说 明 一 个 变 量 :
_ _int8 nSmall ; // 说 明 8 位 整 数
_ _int16 nMedium ; // 说 明 16 位 整 数
_ _int32 nLarge ; // 说 明 32 位 整 数
_ _int64 nHuge ;// 说明 64 位 整 数
类 型 __ int8 、 _ _int16 和 _ _ int32 是 具 有 同 样 尺 寸 的 ANSI 类 型 的 同 义 词 , 对 编 写在 跨 多 平 台 中 行 为 相 同 的 可 移 植 代 码 很 有 用 。 注 意 , __ int8 数 据 类 型 是 类 型 char 的 同 义 词 , _ _ int16 是 类 型 short 的 同 义 词 , __int32 是 类 型 int 的 同 义 词 , __int64 数 据 类 型 在 ANSI 中 没 有 等 价 类 。
由 于 __ int8 、 __int16 和 __ int32 被 编 译 器 认 为 是 对 应 的 同 义 词 , 所 以 在 使 用 这 些类 型 作 参 量 去 重 载 函 数 调 用 时 , 应 加 以 小 心 。 例 如 , 以 下 C++ 代 码 将 产 生 一 个 编译 错 误 。
void MyFunc(_ _int8) {} void MyFunc(char) {}
void main()
{
_ _int8 newVal;
char MyChar;
MyFunc(MyChar); // 不 明 确 的 函 数 调 用 ;
MyFunc(newVal); //char 与 _ _int8 是 同 义 词 。
}
派 生 类 型
派 生 类 型 是 可 被 用 于 程 序 中 , 可 包 含 直 接 派 生 类 型 和 复 合 派 生 类 型 的 新 类 型 。
直 接 派 生 的 类 型
从 已 存 在 类 型 直 接 派 生 的 新 类 型 是 指 向 、 指 示 或 ( 在 函 数 情 形 ) 传 输 类 型 数 据 以返 回 一 个 新 类 型 的 类 型 。
-
变 量 或 对 象 数 组
-
函 数
-
一 个 给 定 类 型 的 指 针
-
对 象 的 引 用
-
常 量
-
类 成 员 指 针
变 量 或 对 象 数 组
变 量 或 对 象 数 组 可 以 包 含 指 定 数 目 的 特 定 类 型 , 例 如 , 从 整 型 派 生 的 数 组 是 一 个类 型 为 int 的 数 组 。 以 下 代 码 例 子 说 明 并 定 义 了 一 个 10 个 int 变 量 的 数 组 和 一个 含 有 类 SampleClass 的 5 个 对 象 的 数 组 :
int ArrayOfInt[10]; SampleClass aSampleClass[5]; 函 数
函 数 有 0 个 或 多 个 给 定 类 型 的 参 量 以 及 返 回 指 定 类 型 的 对 象 ( 或 什 么 也 不 返 回 , 如 果 函 数 具 有 void 返 回 类 型 ) 。
- 个 给 定 类 型 的 指 针
变 量 或 对 象 的 指 针 选 择 存 储 器 中 的 一 个 对 象 。 对 象 可 以 是 全 局 的 、 局 部 的 ( 或 栈结 构 ) 或 动 态 分 配 的 。 给 定 类 型 的 函 数 指 针 允 许 程 序 在 一 个 特 定 对 象 或 多 个 对 象上 的 函 数 延 迟 选 择 直 到 运 行 时 。 以 下 例 子 给 出 了 一 个 指 向 类 型 为 char 的 变 量 的
指 针 定 义 :
char *SzPathStr;
对 象 的 引 用
对 象 的 引 用 为 通 过 引 用 访 问 对 象 提 供 了 一 种 便 利 的 方 法 , 但 与 使 用 通 过 值 访 问 对象 所 要 求 的 语 法 相 同 。 以 下 例 子 描 述 了 如 何 使 用 作 为 函 数 参 量 和 作 为 函 数 返 回类 型 的 引 用 :
BigClassType &func(BigClassType &objname)
{
objname.DoSomething();// 注意 , 使 用 了 成 员 运 算 符 (.)
objname.SomeData=7;// 通 过 非 const 引 用 传 递 的 数 据 是 可 修 改 的 。
return objname;
}
关 于 通 过 引 用 向 函 数 传 递 对 象 的 几 个 要 点 是 :
-
访 问 class 、 struct 和 union 对 象 的 成 员 的 语 法 是 相 同 的 , 就 如 同它 们 通 过 值 : 成 员 运 算 符 (.) 传 递 一 样 。
-
在 函 数 调 用 前 未 拷 贝 对 象 , 传 递 它 们 的 地 址 , 这 可 以 减 少 函 数 调 用 的系 统 开 销 。
另 外 , 返 回 一 个 引 用 的 函 数 仅 需 要 接 收 它 们 所 指 的 对 象 的 地 址 , 而 不 是 整 个 对 象的 拷 贝 。
尽 管 上 面 的 例 子 仅 仅 是 用 函 数 进 行 上 下 文 通 信 中 的 引 用 , 但 引 用 并 不 限 于 此 种 应
用 。 例 如 , 考 虑 一 个 函 数 需 要 l 值 的 情 况 — — 重 载 运 算 符 的 普 通 要 求 : class Vector
{
public:
Point &operator[](int nSubscript); // 函 数 返 回 一 个 引 用 类 型
...
};
上 面 的 说 明 为 类 Vector 指 定 了 一 个 用 户 定 义 的 下 标 运 算 符 。在 一 个 赋 值 语 句 中 , 出 现 两 种 可 能 的 状 态 ;
Vector vl; int i; Point p;
vl[7]=p; //Vector 用 作 一 个 l 值p=vl[7]; //Vector 用 作 一 个 r 值
后 一 种 情 况 , 即 vl[7] 用 作 一 个 r 值 , 可 以 不 用 引 用 去 实 现 。 可 是 , 前 一 种 情 况 , 即 vl[7] 用 作 一 个 l 值 , 如 果 不 用 引 用 类 型 的 函 数 就 不 能 方 便 地 实 现 。 从 概 念 上讲 , 前 面 例 子 中 最 后 两 条 语 句 翻 译 为 以 下 代 码 :
vl.operator[](7)=3; //Vector 用 作 一 个 l 值i=vl.operator[](7); //Vector 用 作 一 个 r 值
当 用 这 种 方 式 去 看 时 , 容 易 看 到 第 一 个 语 句 必 定 为 一 个 l 值 , 在 赋 值 语 句 的 左 侧且 语 义 正 确 。
关 于 重 载 以 及 特 殊 情 况 的 重 载 运 算 符 的 更 多 信 息 , 参 见 第 12 章“ 重 载 ” 中 的“ 重载 运 算 符 ”。
你 还 可 以 使 用 引 用 去 说 明 一 个 变 量 或 对 象 的 一 个 const 引 用 。 说 明 为 const 的一 个 引 用 保 留 了 通 过 引 用 传 递 参 量 的 效 能 , 而 防 止 被 调 用 函 数 修 改 最 初 对 象 。 考虑 以 下 代 码 :
//Invalue 是 一 个 const 引 用 。
void PrintInt(const int &IntValue)
{
printf("%d\n",IntValue);
}
引 用 初 始 化 不 同 于 对 一 个 引 用 类 型 的 变 量 的 赋 值 , 考 虑 以 下 代 码 ; int i=7;
int j=5;
// 引 用 初 始 化
int &ri=i; // 初 始 化 ri 指 向 i 。int &rj=j; // 初 始 化 rj 指 向 j 。
// 赋 值
ri=3; //i 现 在 等 于 3 rj=12; //j 现 在 等 于 12 ri=rj; //i 现 在 等 于 (12) 。
常 量
关 于 C++ 中 允 许 的 各 种 常 量 的 更 多 信 息 参 见 第 1 章 “ 词 法 规 定 ” 中 的 “ 文 字 ”。
类 成 员 指 针
这 些 指 针 定 义 一 个 类 型 指 向 一 个 特 殊 类 型 的 类 成 员 , 这 样 的 一 个 指 针 可 以 被 类 类型 的 任 何 对 象 或 类 类 型 派 生 类 型 的 任 何 对 象 所 使 用 。
使 用 类 成 员 指 针 增 强 了 C++ 语 言 的 类 型 安 全 性 , 如 表 2.5 所 列 的 对 成 员 指 针 可 以使 用 三 种 新 运 算 符 和 结 构 。
表 2.5 和 成 员 一 起 使 用 的 运 算 符 和 结 构
运算符或结构 语法 使用
::* type::*ptr-name 成 员 指 针 说 明 。 type 指 定 类名 , ptr_name 指定成员指针名。成员指针可被初始化 , 例如 : MyType::*pMyType=&MyType:: i
.* obj-name.*ptr-name 使 用 一 个 对 象 或 对 象 引 用 间 接引用一个成员指针 , 例如 :
int j=Object.*pMyType
->* obj_ptr->*ptr_name 使 用 一 个 对 象 指 针 间 接 引 用 一个成员指针 , 例如 :
int j=pObject->*pMyType
考 虑 以 下 例 子 , 该 例 子 中 定 义 了 一 个 类 AClass 和 一 个 派 生 类 型 pDAT, 它 指 向 成
员 I1:
#include <iostream.h>
// 定 义 类 AClass
{
public:
int I1;
Show() { cout << I1 << "\n"; }
};
// 定 义 一 个 派 生 类 型 pDAT, 指 向 类 型 AClass 的 对 象 的 I1 成 员int AClass::*pDAT=&AClass::I1;
void main()
{
AClass aClass; // 定 义 类 型 AClass 的 一 个 对 象 。
AClass *paClass=&aClass; // 定 义 对 象 的 一 个 指 针 。
int i;
aClass.*pDAT=7777; // 用 .* 运 算 符 对 aClass::I1 赋值
aClass.Show();
i=paClass->*pDAT; //* 运 算 符 间 接 引 用 一 个 指 针
cout << i << "\n";
}
成 员 pDAT 的 指 针 是 从 类 AClass 派 生 的 一 个 新 类 型 , 它 是 一 个 比 int 的 “ 普 通 ” 指 针 更 强 壮 的 类 型 , 因 为 它 仅 指 向 类 AClass 的 int 成 员 ( 在 此 情 况 为 I1) 。 静 态成 员 的 指 针 是 普 通 指 针 而 不 是 类 成 员 指 针 , 考 虑 以 下 例 子 :
class HasStaticMember
{
public:
static int SMember;
};
int HasStaticMember::SMember=0;
int *pSMember=&HasStaticMember::SMember;
注 意 , 该 指 针 的 类 型 是 “ int 指 针 ” , 而 不 是 “ HasStaticMember::int 的 指 针 ”。成 员 指 针 可 以 和 成 员 数 据 一 样 指 向 成 员 函 数 , 考 虑 以 下 代 码 :
#include <stdio.h>
// 用 虚 函 数 Identify 说 明 一 个 基 类 A,( 注 意 在 此 上 下 文 中 ,struct 与 类 是 相 同的 )
struct A
{
virtual void Identify()=0; // 类 A 没 有 定 义
};
// 说 明 Identify 成 员 函 数 一 个 指 针
void (A::*pIdentify)()=&A::Identify;
// 说 明 从 类 A 派 生 的 类 B struct B : public A
{
void Identify();
};
// 为 类 B 定义 Identify 函 数void B:Identify()
{
printf("Identification is B::Identify\n");
}
void main()
{
B Bobject; // 说 明 类 型 B 的 对 象
A *pA ;// 说 明 类 型 A 的 指 针
PA=&Bobject;// 使 PA 指 向 类 型 B 的 一 个 对 象
(PA->*pIdentify)(); // 通 过 成 员 pIdentify 的 指 针 调 用 Identify 函 数
}
该 程 序 的 输 出 是 :
Identification is B::Identify
该 函 数 是 通 过 类 型 A 的 一 个 指 针 调 用 的 。 可 是 , 由 于 函 数 是 一 个 虚 函 数 ,pA 所 指对 象 的 正 确 函 数 被 调 用 。
复 合 派 生 类 型
本 节 描 述 以 下 复 合 派 生 类 型 :
-
类
-
结 构
-
联 合
有 关 集 合 类 型 和 集 合 类 型 的 初 始 化 可 参 见 第 7 章“ 说 明 符 ” 中 的“ 集 合 初 始 化 ”。
类
类 是 组 合 在 一 起 的 一 组 成 员 对 象 、 操 作 这 些 成 员 的 函 数 以 及 ( 可 选 的 ) 成 员 对 象和 函 数 的 访 问 控 制 规 格 。
通 过 将 类 中 对 象 和 函 数 进 行 分 组 ,C++ 允 许 程 序 员 创 建 派 生 类 型 , 而 不 仅 是 定 义 数据 , 还 可 以 定 义 对 象 的 行 为 。
类 成 员 在 缺 省 情 况 下 是 私 有 访 问 和 私 有 继 承 的 。 第 8 章 “ 类 ” 中 介 绍 类 。 访 问控 制 包 含 在 第 10 章 “ 成 员 访 问 控 制 ” 中 。
结 构
C++ 的 结 构 与 类 相 同 , 不 同 的 是 所 有 成 员 数 据 和 函 数 缺 省 的 为 公 共 访 问 , 且 继 承 性缺 省 的 为 公 共 继 承 。
有 关 访 问 控 制 的 更 多 信 息 , 参 见 第 10 章 “ 成 员 访 问 控 制 ”。
联 合
联 合 允 许 程 序 员 在 相 同 的 存 储 器 空 间 中 定 义 能 够 包 含 不 同 变 量 的 类 型 。 以 下 代码 给 出 了 如 何 使 用 一 个 联 合 存 储 几 个 不 同 类 型 的 变 量 :
// 说 明 可 以 拥 有 类 型 为 char 、 int 和 char * 的 数 据 的 联 合union ToPrint
{
char chVar;
int iVar;
char *szVar;
};
// 说 明 一 个 枚 举 类 型 , 用 于 描 述 打 印 的 类 型enum PrintType{ CHAR_T,INT_T,STRING_T };
void Print( ToPrint Var,PrintType Type)
{
switch(Type)
{
case CHAR_T:
printf("%c",Var.chVar);
break;
case INT_T:
printf("%d",Var.iVar);
break;
case STRING_T:
printf("%s",Var.szVar);
break;
}
}
类 型 名 称
基 本 的 和 派 生 的 类 型 的 同 义 词 均 可 使 用 typedef 关 键 字 来 定 义 。 以 下 代 码 描 述了 typedef 的 使 用 :
typedef unsigned char BYTE; //8 位 无 符 号 实 体typedef BYTE *PBYTE; // 指 向 BYTE 的 指 针
BYTE Ch; // 说 明 一 个 类 型 BYTE 的 变 量PBYTE pbCh; // 说 明 一 个 指 向 BYTE 变 量 的 指 针
上 面 的 例 子 给 出 了 基 本 类 型 unsigned char 和 其 派 生 类 型 unsigned char * 的统 一 的 说 明 语 法 。 typedef 结 构 对 简 化 说 明 也 很 有 用 。 一 个 typedef 说 明 定 义
- 个 同 义 词 , 而 不 是 一 个 新 的 独 立 类 型 。 以 下 例 子 说 明 了 一 个 表 示 指 向 返 回 类 型为 void 的 函 数 的 指 针 的 类 型 名 (PVFN) 。 这 种 说 明 的 好 处 是 在 后 面 的 程 序 中 这 些指 针 的 数 组 说 明 起 来 非 常 简 单 。
// 两 个 函 数 原 型void func1(); void func2();
// 定 义 PVFN 表 示 一 个 指 向 返 回 类 型 为 void 的 函 数 的 指 针typedef void (*PVFN)();
...
// 说 明 一 个 函 数 指 针 数 组
PVFN pvfn[]={ func1,func2 };
// 调 用 一 个 函 数(*pvfn[1])();
l 值 和 r 值
C++ 中 表 达 式 可 以 求 值 为“ l 值 ”或“ r 值 ”。l 值 是 一 个 表 达 式 , 求 值 为 某 个 非 void 的 类 型 , 且 指 定 一 个 变 量 。
l 值 出 现 在 赋 值 语 句 的 左 侧 ,( 因 此 用 "l" 表示 ), 通 常 为 l 值 的 变 量 可 以 用 const 关 键 字 使 其 不 可 修 改 , 这 样 不 能 出 现 在 赋 值 语 句 的 左 侧 。 引 用 类 型 总 是 l 值 。
术 语 r 值 有 时 用 于 描 述 一 个 表 达 式 的 值 , 且 与 一 个 l 值 区 分 开 来 , 所 有 的 l 值 都是 r 值 , 但 r 值 不 都 是 l 值 。
- 些 正 确 及 错 误 使 用 的 例 子 ;
i=7; // 正 确 变 量 名 i 是 一 个 l 值7=i; // 错 误 常 量 7 是 一 个 r 值
j*4=7; // 错 误 表 达 式 j*4 产 生 一 个 r 值
*p=i; // 正 确 一 个 间 接 引 用 指 针 是 一 个 l 值const int ci=7; // 说 明 一 个 const 变 量
ci=9 //ci 是 一 个 不 可 修 改 的 l 值 , 所 以 赋 值 导 致 一 条 错 误 信 息 的 产 生((i<3) ? i:j )=7; // 正 确 , 条 件 运 算 符 (?:) 返 回 一 个 l 值
注 意 : 本 节 的 例 子 描 述 了 运 算 符 未 重 载 时 的 正 确 的 和 错 误 的 用 法 , 通 过 重 载 运 算符 , 你 可 以 让 一 个 表 达 式 , 如 j*4 成 为 一 个 l 值 。
数 的 限 制
两 个 标 准 包 括 文 件 LIMITS.H 和 FLOAT.H 定 义 了 “ 数 的 限 制 ” 或 一 个 给 定 类 型 变量 所 能 取 的 最 小 和 最 大 值 , 这 些 最 小 值 和 最 大 值 确 保 与 ANSI C 使 用 相 同 数 据 表示 的 任 意 C++ 编 译 器 都 是 可 移 植 的 。 LIMITS.H 包 含 文 件 为 整 型 定 义 数 的 限制 ,FLOAT.H 为 浮 点 类 型 定 义 数 的 限 制 。
整 数 限 制
Microsoft 特 殊 处 →
整 数 类 型 的 限 制 列 在 表 2.6 中 , 这 些 限 制 同 时 定 义 在 标 准 头 文 件 LIMITS.H 中 。
表 2.6 整 型 常 量 的 限 制 常 量
常量 |
含义 |
值 |
||||||
---|---|---|---|---|---|---|---|---|
CHAR_BIT |
不是位域的最小变量的位数 |
8 |
||||||
SCHAR_MIN |
signed char 类型变量的最小值 |
-128 |
||||||
SCHAR_MAX |
signed char 类型变量的最大值 |
127 |
||||||
UCHAR_MAX |
unsigned char 类型变量的最大值 |
255(0xff) |
||||||
CHAR_MIN |
char 类型变量的最小值 |
-128; 如果用 /J 选项为 0 |
||||||
CHAR_MAX |
char 类型变量的最大值 |
127; 如果用 /J 选项为 255 |
||||||
MB_LEN_MAX |
在多字符常量中最大字节数 |
2 |
||||||
SHRT_MIN |
short 类型变量的最小值 |
-32768 |
||||||
SHRT_MAX |
short 类型变量的最大值 |
32767 |
||||||
USHRT_MAX INT_MIN |
unsigned short 类值 类型变量的最小值 |
型 |
变 |
量 |
的 |
最 |
大 |
65535(0xffff) -2147483647-1 |
INT_MAX |
类型变量的最大值 |
2147483647 |
||||||
UINT_MAX |
unsigned int 类型变量的最大值 |
4294967295(0xffffffff |
||||||
) |
||||||||
LONG_MIN |
long 类型变量的最小值 |
-2147483647-1 |
LONG_MAX Long 类型变量的最大值 2147483647
ULONG_MAX unsigned long 类型变量的最大值 424967295(0xffffffff) 如 果 数 值 超 过 了 最 大 的 整 数 表 示 范 围 , 则 Microsoft 编 译 器 产 生 错 误 。Microsoft 特 殊 处 结 束
浮 点 数 限 制Microsoft 特 殊 处 →
表 2.7 列 出 了 浮 点 常 量 值 的 限 制 , 这 些 限 制 同 时 定 义 在 标 准 头 文 件 FLOAT.H 中 。
表 2.7 浮 点 常 量 限 制
常量 含义 值
FLT_DIG DBL_DIG LDBL_DIG
数字个数 q, 即具有 q 个十进制数 字 的 浮 点 数 可 舍 入 为 一 个 浮点 表 示 , 而 且 返 过 来 不 损 失 精度
6
15
15
FLT_EPSILON 最小的正数 x, 如 x+1.0 不等于
1.0
1.19202896e-07F
DBL_EPSILON 2.2204460492503131e-
016
LDBL_EPSILON 2.2204460492503131e-
016
FLT_GUARD 0
FLT_MANT_DIG 在 浮 点 有 效 数 中 由 FLT_RADIX 24
指定的
DBL_MANT_DIG |
基数中的数字位数。基数为 2; |
53 |
---|---|---|
LDBL_MANT_DIG |
因此这些值指定位数 |
53 |
FLT_MAX DBL_MAX |
最大的可表示的浮点数 |
3.402823466e+38f 1.7976931348623158e+3 |
LDBL_MAX |
08 1.7976931348623158e+3 |
|
08 |
||
FLT_MAX_10_EX |
最大整数 ,10 的这个数的乘方 |
38 |
P DBL_MAX_10_EX |
是可表示的浮点数 |
308 |
P LDBL_MAX_10_E |
308 |
|
XP FLT_MAX_EXP |
最大整数 ,FLT_RADOX 的这个数 |
128 |
DBL_MAX_EXP |
的乘方 是可表示的浮点数 |
1024 |
LDBL_MAX_EXP FLT_MIN |
最小的正值 |
1024 1.175494351e-38F |
DBL_MIN |
2.2250738585072014e- 308 |
|
LDBL_MIN |
2.2250738585072014e- 308 |
FLT_MIN_10_EX P
最 小 负 整 数 ,10 的 这 个 数 的 乘方
-37
DBL_MIN_10_EX P |
是可表示的浮点数 |
-307 |
|
---|---|---|---|
LDBL_MIN_10_E XP |
-307 |
||
FLT_MIN_EXP |
最小负整数 ,FLT_RADIX 的乘方 |
这个数 |
-125 |
DBT_MIN_EXP |
是可表达的浮点数 |
-1021 |
|
LDBT_MIN_EXP |
-1021 |
||
FLT_NORMALIZE |
0 |
||
FLT_RADIX |
指数表示的基数 |
2 |
|
_DBL_RADIX |
2 |
||
_LDBL_RADIX |
2 |
||
FLT_ROUNDS _DBL_ROUNDS |
浮点加法的舍入模式 |
1( 近 ) 1( 近 ) |
|
_LDBL_ROUNDS |
1( 近 ) |
注 意 , 表 2.7 中 的 信 息 可 能 在 产 品 的 未 来 版 本 中 有 所 不 同 。
Microsoft 特 殊 处 结 束