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 中 的 argcargvenvp 参量 : #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 特 殊 处 结 束