《C指针详解(经典-非常详细)》由会员分享,可在线阅读,更多相关《C指针详解(经典-非常详细)(29页珍藏版)》请在金锄头文库上搜索。
1、让 你 不 再 害 怕 指 针前 言 :复 杂 类 型 说 明要 了 解 指 针 ,多 多 少 少 会 出 现 一 些 比 较 复 杂 的 类 型 ,所 以 我 先 介 绍一 下 如 何 完 全 理 解 一 个 复 杂 类 型 ,要 理 解 复 杂 类 型 其 实 很 简 单 ,一个 类 型 里 会 出 现 很 多 运 算 符 ,他 们 也 像 普 通 的 表 达 式 一 样 ,有 优 先级 ,其 优 先 级 和 运 算 优 先 级 一 样 ,所 以 我 总 结 了 一 下 其 原 则 :从 变 量 名 处 起 ,根 据 运 算 符 优 先 级 结 合 ,一 步 一 步 分 析 .下 面 让
2、我 们 先 从 简 单 的 类 型 开 始 慢 慢 分 析 吧 :int p; /这 是 一 个 普 通 的 整 型 变 量int *p; /首 先 从 P处 开 始 ,先 与 *结 合 ,所 以 说 明 P 是 一/个 指 针 ,然 后 再 与 int结 合 ,说 明 指 针 所 指 向/的 内 容 的 类 型 为 int 型 .所 以 P是 一 个 返 回 整/型 数 据 的 指 针int p3; /首 先 从 P处 开 始 ,先 与 结 合 ,说 明 P 是 一 个 数/组 ,然 后 与 int结 合 ,说 明 数 组 里 的 元 素 是 整/型 的 ,所 以 P是 一 个 由 整 型
3、数 据 组 成 的 数 组int *p3; /首 先 从 P处 开 始 ,先 与 结 合 ,因 为 其 优 先 级/比 *高 ,所 以 P是 一 个 数 组 ,然 后 再 与 *结 合 ,说 明/数 组 里 的 元 素 是 指 针 类 型 ,然 后 再 与 int结 合 ,/说 明 指 针 所 指 向 的 内 容 的 类 型 是 整 型 的 ,所 以/P 是 一 个 由 返 回 整 型 数 据 的 指 针 所 组 成 的 数 组int (*p)3;/首 先 从 P处 开 始 ,先 与 *结 合 ,说 明 P是 一 个 指 针/然 后 再 与 结 合 (与 ()这 步 可 以 忽 略 ,只 是
4、为/了 改 变 优 先 级 ),说 明 指 针 所 指 向 的 内 容 是 一 个/数 组 ,然 后 再 与 int 结 合 ,说 明 数 组 里 的 元 素 是/整 型 的 .所 以 P 是 一 个 指 向 由 整 型 数 据 组 成 的 数/组 的 指 针int *p; /首 先 从 P开 始 ,先 与 *结 合 ,说 是 P是 一 个 指 针 ,然/后 再 与 *结 合 ,说 明 指 针 所 指 向 的 元 素 是 指 针 ,然/后 再 与 int结 合 ,说 明 该 指 针 所 指 向 的 元 素 是 整/型 数 据 .由 于 二 级 指 针 以 及 更 高 级 的 指 针 极 少 用
5、/在 复 杂 的 类 型 中 ,所 以 后 面 更 复 杂 的 类 型 我 们 就/不 考 虑 多 级 指 针 了 ,最 多 只 考 虑 一 级 指 针 .int p(int); /从 P处 起 ,先 与 ()结 合 ,说 明 P是 一 个 函 数 ,然 后 进 入/()里 分 析 ,说 明 该 函 数 有 一 个 整 型 变 量 的 参 数/然 后 再 与 外 面 的 int 结 合 ,说 明 函 数 的 返 回 值 是/一 个 整 型 数 据Int (*p)(int); /从 P处 开 始 ,先 与 指 针 结 合 ,说 明 P是 一 个 指 针 ,然 后 与/()结 合 ,说 明 指 针
6、 指 向 的 是 一 个 函 数 ,然 后 再 与 ()里 的/int 结 合 ,说 明 函 数 有 一 个 int 型 的 参 数 ,再 与 最 外 层 的/int 结 合 ,说 明 函 数 的 返 回 类 型 是 整 型 ,所 以 P 是 一 个 指/向 有 一 个 整 型 参 数 且 返 回 类 型 为 整 型 的 函 数 的 指 针int *(*p(int)3; /可 以 先 跳 过 ,不 看 这 个 类 型 ,过 于 复 杂/从 P开 始 ,先 与 ()结 合 ,说 明 P是 一 个 函 数 ,然 后 进/入 ()里 面 ,与 int结 合 ,说 明 函 数 有 一 个 整 型 变
7、量/参 数 ,然 后 再 与 外 面 的 *结 合 ,说 明 函 数 返 回 的 是/一 个 指 针 ,然 后 到 最 外 面 一 层 ,先 与 结 合 ,说 明/返 回 的 指 针 指 向 的 是 一 个 数 组 ,然 后 再 与 *结 合 ,说/明 数 组 里 的 元 素 是 指 针 ,然 后 再 与 int 结 合 ,说 明 指/针 指 向 的 内 容 是 整 型 数 据 .所 以 P是 一 个 参 数 为 一 个/整 数 据 且 返 回 一 个 指 向 由 整 型 指 针 变 量 组 成 的 数 组/的 指 针 变 量 的 函 数 .说 到 这 里 也 就 差 不 多 了 ,我 们 的
8、 任 务 也 就 这 么 多 ,理 解 了 这 几 个 类 型 ,其 它的 类 型 对 我 们 来 说 也 是 小 菜 了 ,不 过 我 们 一 般 不 会 用 太 复 杂 的 类 型 ,那 样 会大 大 减 小 程 序 的 可 读 性 ,请 慎 用 ,这 上 面 的 几 种 类 型 已 经 足 够 我 们 用 了 .1、 细 说 指 针指 针 是 一 个 特 殊 的 变 量 , 它 里 面 存 储 的 数 值 被 解 释 成 为 内 存 里 的 一 个 地 址 。要 搞 清 一 个 指 针 需 要 搞 清 指 针 的 四 方 面 的 内 容 : 指 针 的 类 型 、 指 针 所 指 向 的
9、类 型 、 指 针 的 值 或 者 叫 指 针 所 指 向 的 内 存 区 、 指 针 本 身 所 占 据 的 内 存 区 。 让我 们 分 别 说 明 。先 声 明 几 个 指 针 放 着 做 例 子 :例 一 :(1)int*ptr;(2)char*ptr;(3)int*ptr;(4)int(*ptr)3;(5)int*(*ptr)4;1.指 针 的 类 型从 语 法 的 角 度 看 , 你 只 要 把 指 针 声 明 语 句 里 的 指 针 名 字 去 掉 , 剩 下 的 部分 就 是 这 个 指 针 的 类 型 。 这 是 指 针 本 身 所 具 有 的 类 型 。 让 我 们 看 看
10、 例 一 中 各个 指 针 的 类 型 :(1)int*ptr;/指 针 的 类 型 是 int*(2)char*ptr;/指 针 的 类 型 是 char*(3)int*ptr;/指 针 的 类 型 是 int*(4)int(*ptr)3;/指 针 的 类 型 是 int(*)3(5)int*(*ptr)4;/指 针 的 类 型 是 int*(*)4怎 么 样 ? 找 出 指 针 的 类 型 的 方 法 是 不 是 很 简 单 ?2.指 针 所 指 向 的 类 型当 你 通 过 指 针 来 访 问 指 针 所 指 向 的 内 存 区 时 , 指 针 所 指 向 的 类 型 决 定 了编 译
11、器 将 把 那 片 内 存 区 里 的 内 容 当 做 什 么 来 看 待 。从 语 法 上 看 , 你 只 须 把 指 针 声 明 语 句 中 的 指 针 名 字 和 名 字 左 边 的 指 针 声明 符 *去 掉 , 剩 下 的 就 是 指 针 所 指 向 的 类 型 。 例 如 :(1)int*ptr; /指 针 所 指 向 的 类 型 是 int(2)char*ptr; /指 针 所 指 向 的 的 类 型 是 char(3)int*ptr; /指 针 所 指 向 的 的 类 型 是 int*(4)int(*ptr)3; /指 针 所 指 向 的 的 类 型 是 int()3(5)in
12、t*(*ptr)4;/指 针 所 指 向 的 的 类 型 是 int*()4在 指 针 的 算 术 运 算 中 , 指 针 所 指 向 的 类 型 有 很 大 的 作 用 。指 针 的 类 型 (即 指 针 本 身 的 类 型 )和 指 针 所 指 向 的 类 型 是 两 个 概 念 。 当 你对 C 越 来 越 熟 悉 时 , 你 会 发 现 , 把 与 指 针 搅 和 在 一 起 的 类 型 这 个 概 念 分 成指 针 的 类 型 和 指 针 所 指 向 的 类 型 两 个 概 念 , 是 精 通 指 针 的 关 键 点 之 一 。我 看 了 不 少 书 , 发 现 有 些 写 得 差
13、的 书 中 , 就 把 指 针 的 这 两 个 概 念 搅 在 一 起 了 ,所 以 看 起 书 来 前 后 矛 盾 , 越 看 越 糊 涂 。3.指 针 的 值 -或 者 叫 指 针 所 指 向 的 内 存 区 或 地 址指 针 的 值 是 指 针 本 身 存 储 的 数 值 , 这 个 值 将 被 编 译 器 当 作 一 个 地 址 , 而不 是 一 个 一 般 的 数 值 。 在 32 位 程 序 里 , 所 有 类 型 的 指 针 的 值 都 是 一 个 32位整 数 , 因 为 32 位 程 序 里 内 存 地 址 全 都 是 32 位 长 。 指 针 所 指 向 的 内 存 区 就
14、是 从 指 针 的 值 所 代 表 的 那 个 内 存 地 址 开 始 , 长 度 为 si zeof(指 针 所 指 向 的 类型 )的 一 片 内 存 区 。 以 后 , 我 们 说 一 个 指 针 的 值 是 XX, 就 相 当 于 说 该 指 针 指向 了 以 XX 为 首 地 址 的 一 片 内 存 区 域 ; 我 们 说 一 个 指 针 指 向 了 某 块 内 存 区 域 ,就 相 当 于 说 该 指 针 的 值 是 这 块 内 存 区 域 的 首 地 址 。指 针 所 指 向 的 内 存 区 和 指 针 所 指 向 的 类 型 是 两 个 完 全 不 同 的 概 念 。 在 例一
15、 中 , 指 针 所 指 向 的 类 型 已 经 有 了 , 但 由 于 指 针 还 未 初 始 化 , 所 以 它 所 指 向的 内 存 区 是 不 存 在 的 , 或 者 说 是 无 意 义 的 。以 后 , 每 遇 到 一 个 指 针 , 都 应 该 问 问 : 这 个 指 针 的 类 型 是 什 么 ? 指 针 指的 类 型 是 什 么 ? 该 指 针 指 向 了 哪 里 ? ( 重 点 注 意 )4 指 针 本 身 所 占 据 的 内 存 区指 针 本 身 占 了 多 大 的 内 存 ? 你 只 要 用 函 数 sizeof(指 针 的 类 型 )测 一 下就 知 道 了 。 在 3
16、2位 平 台 里 , 指 针 本 身 占 据 了 4个 字 节 的 长 度 。指 针 本 身 占 据 的 内 存 这 个 概 念 在 判 断 一 个 指 针 表 达 式 ( 后 面 会 解 释 ) 是否 是 左 值 时 很 有 用 。2、 指 针 的 算 术 运 算指 针 可 以 加 上 或 减 去 一 个 整 数 。 指 针 的 这 种 运 算 的 意 义 和 通 常 的 数 值 的 加 减运 算 的 意 义 是 不 一 样 的 , 以 单 元 为 单 位 。 例 如 :例 二 :char a20;int *ptr=(int *)a; /强 制 类 型 转 换 并 不 会 改 变 a的 类 型ptr+;在 上 例 中 , 指 针 ptr 的 类 型 是 int*,它 指 向 的 类 型 是 int, 它