




已阅读5页,还剩15页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1 1 指针函数的定义指针函数的定义 顾名思义 指针函数即返回指针的函数 其一般定义形式如下 类型名类型名 函数名函数名 函数参数表列函数参数表列 其中 后缀运算符括号 表示这是一个函数 其前缀运算符星号 表示此函数为指针型函数 其函数值为指针 即它带回来的值的类型为指针 当调用这个函数后 将得到一个 指向返回值为 的指针 地址 类型名类型名 表示函数返回的指针指向的类型 函数参数表列函数参数表列 中的括号为函数调用运算符 在调用语句中 即使函 数不带参数 其参数表的一对括号也不能省略 其示例如下 int pfun int int 由于 的优先级低于 的优先级 因而 pfun 首先和后面的 结合 也就意味着 pfun 是一个函数 即 int pfun int int 接着再和前面的 结合 说明这个函数的返回值是一个指针 由于前面 还有一个 int 也就是说 pfun 是一个返回值为整型指针的函数 我们不妨来再看一看 指针函数与函数指针有什么区别 int pfun int int 通过括号强行将 pfun 首先与 结合 也就意味着 pfun 是一个指针 接着与后面的 结合 说明该指针指向的是一个函数 然后再与前面的 int 结合 也就是说 该函数的返回值是 int 由此可见 pfun 是一个指向返 回值为 int 的函数的指针 虽然它们只有一个括号的差别 但是表示的意义却截然不同 函数指针的 本身是一个指针 指针指向的是一个函数 指针函数的本身是一个函数 其函 数的返回值是一个指针 2 2 用函数指针作为函数的返回值用函数指针作为函数的返回值 在上面提到的指针函数里面 有这样一类函数 它们也返回指针型数据 地址 但是这个指针不是指向 int char 之类的基本类型 而是指向函数 对于初学者 别说写出这样的函数声明 就是看到这样的写法也是一头雾水 比如 下面的语句 int ff int int int 我们用上面介绍的方法分析一下 ff 首先与后面的 结合 即 int ff int int int 用括号将 ff int 再括起来 也就意味着 ff 是一个函数 接着与前面的 结合 说明 ff 函数的返回值是一个指针 然后再与后 面的 结合 也就是说 该指针指向的是一个函数 这种写法确实让人非常难懂 以至于一些初学者产生误解 认为写出别人 看不懂的代码才能显示自己水平高 而事实上恰好相反 能否写出通俗易懂的 代码是衡量程序员是否优秀的标准 一般来说 用 typedef 关键字会使该声明 更简单易懂 在前面我们已经见过 int PF int int 也就是说 PF 是一个函数指针 变量变量 当使用 typedef 声明后 则 PF 就成 为了一个函数指针 类型类型 即 typedef int PF int int 这样就定义了返回值的类型 然后 再用 PF 作为返回值来声明函数 PF ff int 下面将以程序清单 1 为例 说明用函数指针作为函数的返回值的用法 当 程序接收用户输入时 如果用户输入 d 则求数组的最大值 如果输入 x 则求 数组的最小值 如果输入 p 则求数组的平均值 程序清单 1 求最值与平均值示例 1 include 2 include 3 double GetMin double dbData int iSize 求最小 值 4 5double dbMin 6int i 7 8assert iSize 0 9dbMin dbData 0 10for i 1 idbData i 12 dbMin dbData i 13 14 15return dbMin 16 17 18 double GetMax double dbData int iSize 求最 大值 19 20double dbMax 21int i 22 23assert iSize 0 24dbMax dbData 0 25for i 1 i iSize i 26 if dbMax0 39for i 0 i iSize i 40 41 dbSum dbData i 42 43return dbSum iSize 44 45 46 double UnKnown double dbData int iSize 未知算 法 47 48return 0 49 50 51 typedef double PF double dbData int iSize 定义函数 指针类型 52 PF GetOperation char c 根据 字符得到操作类型 返回函数指针 53 54switch c 55 56case d 57 return GetMax 58case x 59 return GetMin 60case p 61 return GetAverage 62default 63 return UnKnown 64 65 66 67 int main void 68 69double dbData 3 1415926 1 4142 0 5 999 313 365 70int iSize sizeof dbData sizeof dbData 0 71char c 72 73printf Please input the Operation n 74c getchar 75printf result is lf n GetOperation c dbData iSize 通过函数指针调用函数 76 上述程序中前面 4 个函数分别实现求最大值 最小值 平均值和未知算法 然后 实现了 GetOperation 函数 这个函数根据字符的返回值实现上面 4 个函数 它是以函数指 针的形式返回的 从后面的 main 函数的 GetOperation c dbData iSize 可以看出 通过这个 指针可以调用函数 声明 在这一个系列中本着一题多解 步步深入以及尽量降低初学者的阅 读难度减少枝叶代码的精神 很多细节都没有处理 例如举的例子中的函数的 返回值都是 void 函数中间没有安全检查 及其它的一些问题 通过例子中的 几十行代码不可能做的面面俱到 在实际编程中是不能这样的 请同学们不要 盲目效仿 在程序设计时 我们经常用 if 或 switch 语句作为条件判断 调用不同的 函数 比如 在菜单驱动软件中 程序提示用户从菜单中选择一个选项 每一 个选项都有一个不同的函数来完成其相应的功能 如果使用函数指针 将指向每一个函数的指针存储在一个指向函数的指针 变量中 例如 函数 void CreateFile 的 CreateFile 会被解释为该函数 的指针 我们可以将其赋给同类型的指针 从而实现一个函数指针调用不同的 函数 这样会使程序更简洁 更专业 下面将利用函数指针来调用 switch 中的 各个函数 详见程序清单 程序清单 4 利用函数指针实现多分支选项 V0 4 1void CmdRunning 2 3int iCmdNum 0 4void pCmd NULL 5 6 do 7 pCmd NULL 8 printf 请选择 0 退出 1 新建文件 2 打开文件 3 保存 文件 n 9 iCmdNum getchar 10 fflush stdin 11 switch iCmdNum 12 case 0 13 printf 谢谢使用 再见 n 14 break 15 case 1 16 pCmd CreateFile 17 break 18 case 2 19 pCmd OpenFile 20 break 21 case 3 22 pCmd SaveFile 23 break 24 default 25 printf 对不起 你选择的数字不存在 请重新选择 n 26 27 if NULL pCmd 28 pCmd 与 pCmd 等价 29 30 while 0 iCmdNum 31 这种方式代码虽然简洁 但是这种形式的扩展性很差 如果想要扩展功能 需要修改两个地方 第一 打印的帮助信息 它不能做到动态绑定 这也是程 序员在开发过程中很容易被忽略的地方 因为它不会影响程序的使用功能 其 次 对于添加 case 语句及处理函数 还有没有更好的实现方式呢 后面的例子 会给大家更深入的讲解这个问题 由此可见 除了可以通过 函数名 调用函数之外 还可以通过 指向函 数的指针变量 调用相应的函数 但用函数名调用函数 只能调用所指定的一 个函数 而如果通过指针变量调用函数 则更加灵活 可以根据不同情况先后 调用不同的函数 控制台选项的实现 控制台选项的实现 3 用用 switch 简化逻辑简化逻辑 更新更新 2 2010 09 27 00 37 46 转载 标签 switch 语句 多分支选项 控制台菜单 教育 声明 在这一个系列中本着一题多解 步步深入以及尽量降低初学者的阅读 难度减少枝叶代码的精神 很多细节都没有处理 例如举的例子中的函数的返 回值都是 void 函数中间没有安全检查 及其它的一些问题 通过例子中的几 十行代码不可能做的面面俱到 在实际编程中是不能这样的 请同学们不要盲 目效仿 与此同时 由于使用 if else 处理多分支选项显得更加繁琐且效率低下 它必 须一个一个分支的判断 而处理多分支比较容易想到的就是 switch 语句了 为 了避免出现 V0 1 中的死循环 我们后面的例子将使用另外一个输入函数 代码 详见程序清单 3 程序清单 3 用 switch 语句做分支处理 V0 3 1voidCmdRunning 2 3 int iCmdNum 0 1 4 5 do 6 printf 请选择 0 退出 1 新建文件 2 打开文件 3 保存文件 n 7 iCmdNum getchar 获得一个字符 8 fflush stdin 清空缓 冲区 9 switch iCmdNum 10 case 0 11 printf 谢谢使用 再见 n 12 break 13 case 1 14 CreateFile 15 break 16 case 2 17 OpenFile 18 break 19 case 3 20 SaveFile 21 break 22 default 23 printf 对不起 你选择的数字不存在 请重新选择 n 24 25 while 0 iCmdNum 26 对于初学者来说 如果能够独立地写出这个版本 则说明已经达到了本科毕业的基本要 求 现行教科书上的许多例子 几乎都是以这种形式出现的 而采用这种思路设计的代码 其扩展性却很差 下文预告下文预告 现行很多教学参考书上的例子 几乎都是以这种形式出现的 其扩展性很 差 通过之前介绍的范例可以看出 打印的帮助信息 同样也不能做到动态 绑定 同时还需要用手工添加 case 语句及处理函数 这是开发过程中最容易被 忽略的问题 初学者容易忽略的整型数据的有关知识初学者容易忽略的整型数据的有关知识 2010 09 27 00 19 34 转载 标签 字长的测量 负数的表示方法 溢出 整数的安全性 补码 教育 1 字长的测试字长的测试 至于各种不同的数据类型在不同的系统中所占用的字节数 则可以使用 sizeof 关键字 注意 初学者往往误认为函数 它是 31 个关键字中的一个 进 行测试 顾名思义 sizeof 就是 size of 返回操作数的类型的长度 以字节为 单位 其一般的表示形式为 sizeof 数据类型 sizeof 变量 比如 sizeof int 4 也就是说 其返回 int 变量的字节数为 4 题外话 明明所有的教材上都说 C 语言一共有 32 个关键字 为什么说是 31 个呢 那么 从今天开始 请记住 C 语言只有 31 个有效的关键 如果那 个再说 32 个 那肯定是脑子进水了 因为 auto 是从 C 语言的无类型前身 B 语 言继承下来的 由于 B 语言没有类似 int 这样的关键字 因此声明必须包含存 储类型 而事实上 auto 已经毫无用途 如果那个老师再出这个题 而你考试恰 好差一分不及格 请将这段话告诉他们 让他们给你 60 分 当然 这段话不会 写在教材上 权当大家看博客累了 开个玩笑而已 不要当真 2 负数的表示方法负数的表示方法 当需要带符号的 signed 整数时 虽然可以单独指定某位为 1 来表示 符号 但计算机不会简单地将 符号位 加到一个数上去 这样反而会使计算机的 运算器的设计更加复杂 那么负数在计算机中是如何存储的呢 规定最高位为 符号位 也就是说 其最高有效位的数字具有不同的 权值 即当其最高有 效位为 0 时 其权值为 2n 1 否则其权值为 2n 1 比如 当一个 8 位二进制数 10110111 被解释为一个无符号数数时 那么其十进制数的多项式求值结果为 10110111 2 1 27 1 25 1 24 1 22 1 21 1 20 183 10 如果解释为一个带符号数时 则其十进制数的多项式求值结果为 10110111 2 1 27 1 25 1 24 1 22 1 21 1 20 73 10 当约定用最高有效位作为符号位来确定 singned 整数之后 这样就可以使用 补码 将符号位和其它位统一处理 那么减法也就可以作为加法来处理了 其规则如下 一个 n 位二进制原码为 N 它的补码可定义为 N 补 2n N 当两个用补码表示的数相加时 如果最高位 符号位 有进位 则进位位 被舍弃 正数的补码与其原码一样 而负数的补码 其符号位为 1 最简单的 算法就是取反该数绝对值原码的所有位 然后将结果加 1 由此可见 在计算 机中数值一律用补码来表示 存储 3 溢出溢出 我们知道 一个 n 位二进制数用于表示 unsigned 数时 其可能的取值范围 为 0 2n 1 比如 一个 8 位数的范围在 0 28 1 0 255 之间 假设在一 个 8 位 unsigned 数 248 上加 10 那么需要 9 位才能存储正确的结果 258 而正 确结果 258 与实际结果 2 最低 8 位有效位 之间的差 256 对应的第 9 位被 丢弃了 因此它不能存储在结果中 当用于表示 signed 数时 则只有一半用于正值 一半用于负值 因此 2 的 补码带符号数的整个取值范围为 2n 2n 1 即一个 8 位二进制数可以保存一个 范围在 27 27 1 128 127 之间的带符号值 因此对于 signed 数 当加上 具有不同符号的数或减去具有相同符号的数时 将永远不会溢出 如果将两个 具有相同符号的整数相加 或将两个具有不同符号的整数相减时 将可能发生 溢出 比如 从一个 8 位 signed 整数 120 中减去 20 即 120 20 10 10001000 11101000 2 01110100 2 116 10 而其正确的结果 140 需要 9 位才能存储 因此正确结果 140 与实际结果 116 最低 8 位有效位 之间的差 256 对应的第 9 位被丢弃了 它不能存储 在结果中 由于整数数据类型的溢出是悄悄发生的 因此一定要注意每个变量可能的 取值范围 4 整数的安全性整数的安全性 2004 年 12 月 25 日 星期六 Comair 航空公司被迫停止了所有的业务 1100 个航班无法起飞 这起事故源于 Comair 所使用的机组调度软件中的一个 16 位计数器 在任何月份 它最多只能表示 32768 次改变 而该月早期频繁的 风暴导致过多的机组重新调配 从而使该 16 位计数器溢出 这起整数漏洞完全 是因为整数表示的局限性所引起的 其实 所有的整数漏洞都是由整型范围错误所引起的 比如 发生整数溢 出是因为在整数操作时产生了超过特定整型表示范围的数值所致 发生符号错 误是因为负数被存放在无法容纳该值范围的带符号类型中 而发生截断错误则 是因为结果被存放在一个过小的类型中 由于整数漏洞都是类型范围错误 所 以只要适当地应用类型范围检查 即可消除所有的整型漏洞 其主要措施有范 围检查 强制类型转换 编译器运行时检查 安全的整数操作 任意精度的算 术 测试与源代码审查 其实际意义上的漏洞防范将结合后续相关的示例另行 说明 简而言之 可利用的软件漏洞都是由本可避免的软件缺陷所引起的 因此 只要揭示最可能导致安全缺陷的编程错误 从一开始就将安全性建立于系统之 内 而不是将其作为补救措施附加进来 如何构建高质量的系统 让软件具有 更少的漏洞 不易遭受代价高昂或后果严重的攻击 这是每一个程序员必须认 真面对的根本问题 由于初学者对这两个概念总是有点蒙查查 所以特意在新的教材写了这一节内容 由于初学者对这两个概念总是有点蒙查查 所以特意在新的教材写了这一节内容 1 数据缓冲区数据缓冲区 我们知道 当用户通过键盘输入数据时 scanf 函数只有检测到 n 符 计算 机才认为用户数据输入完毕 而包括回车符在内的数据总得有个落脚点吧 当然 聪明的 计算机设计大师绝不会让用户输入的有价值的数据无缘无故地消失掉 他们早已考虑了这 些细节问题 事先为这些数据的去处作了充分周密的安排 与极速运行的 CPU 相比 数据的输入 输出和键盘的 I O 接口是一个极其缓慢的外设 为了减少 CPU 的等待时间 因此在内存中开辟了一个叫做 缓冲区 的存储单元 用于保 存输入或输出数据 缓冲区 其实相当于一个仓库 其示意图详见图 4 2 略 打一个比方 通过键盘输入数据 好比正在生产产品的工厂 缓冲区 就像仓库 用于放置已经生产出来的产品 而 读取数据 则好比卖东西的门 市部 我们想一想 如果没有仓库 则工厂生产出来的产品就没地方放置 必 须生产一个产品 门市部再去取一个产品 然后再生产再取 如果生产 10 个产 品就得来回跑 10 趟 这样岂不是很浪费资源 于是就有了仓库 工厂不再需要 直接和门市部打交道 它只需要将生产好的产品放到仓库就行 而门市部也不 需要立即去处理已经生产的产品 当要用的时候再去仓库取就好了 由此可见 从键盘输入数据存放到缓冲区 即相当于工厂将生产好的产品放 到仓库中 而从缓冲区读取数据 即相当于从仓库取走产品 当 scanf 函数检测到 n 符时 则立即从缓冲区中取走输入数据赋值 给变量 但却不会取走对用户来说无效的 n 符 虽然 n 符用 作输入数据结束的标志符 但也可作为每一行源代码结束的标志符 此时 即使用户第二次执行读取数据操作 而计算机则会直接跳过去 因为 缓冲区内只有 n 符 其实这些可能的不合情理的操作 计算机设计大 师犹如神机妙算早已料到 每次都会让计算机检测缓冲区是非为空 只有缓冲 区不空时 才允许执行读取数据操作 2 变量的地址变量的地址 虽然 缓冲区 这个名字对于初学者来说是第一次接触 但实际上它仅仅是 一个 中转站 而已 因此也不需要知道保存这些数据的存储单元地址 而变 量则不一样 它在内存中必须具有确定的位置 否则无法一直保存以备再次使 用 那么到底如何获得变量的地址呢 C 语言用 定义了一个整型值变量 num 并初始化为 1 通过前面的学习 我们知道 num 是变量名 变量 num 的值为 1 那么保存 数值 1 的变量的地址就是 即就是将从键盘输入的数据存放到缓冲区 当检测到 n 符时 则立即 从缓冲区读取数据赋值给变量 num 3 输入函数格式输入函数格式 用 scanf 函数输入数据的一般形式如下 scanf 格式控制 地址表列 格式控制 与 printf 函数完全相同 它同样包括 格式声明和普通字符 信息 而 地址表列 则是由若干个地址所组成的表列 因此既可为变量的地 址 也可为字符串的首地址 控制台菜单选项的实现 控制台菜单选项的实现 2 入口检查入口检查 2010 09 27 00 00 09 转载 标签 入口检查 字符变量 测试用例 教育 声明 在这一个系列中本着一题多解 步步深入以及尽量降低初学者的阅读 难度减少枝叶代码的精神 很多细节都没有处理 例如举的例子中的函数的返 回值都是 void 函数中间没有安全检查 及其它的一些问题 通过例子中的几 十行代码不可能做的面面俱到 在实际编程中是不能这样的 请同学们不要盲 目效仿 在 V0 1 版本中 我们提到了输入参数的合法性检查问题 不过还是先介绍 另一个非常重要的理念 健壮性 在大多数本科教材中也只是提到了这 个概念 却并没有深入的去探讨 其实不然 对于一个合格的程序员来说 软 件的健壮性理念必须放在首位 很多到企业实习的学生编写的代码 一般都能 够正确地实现程序的功能 一些学生甚至还会做到功能上的扩展 但是所有的 学生都有一个共同的毛病 从来不做异常处理 只要用户输入不合法 则程序 很容易崩溃 这是不允许发生的 也是用户绝对不能容忍的 虽然软件在发布 前必须经过大量的测试 但希望初学者必须养成良好的编程习惯 下面开始讨论 V0 1 版本软件接受用户输入的合法性判断 为什么要重点判 断这个问题呢 道理很简单 用户都是傻瓜 当然 我们不是说使用者智 商有任何问题 而是开发人员应该这么去想 开发者无法预知用户会输入那些 奇奇怪怪的内容 但是好的程序都必须能够处理那些看来莫名其妙的问题 我 们到底将如何解决这样的问题呢 1 方法方法 1 scanf d 语句是 V0 1 版本出现死循环的关键 那么我们 不妨先从这里入手 其实只要将 d 改为 c 即可解决死循环问题 比如 scanf c chCmd 是一个字符变 量 iCmdNum atoi 将 chCmd 转 换为整型数值 为什么这样做就能够解决死循环问题呢 我们不妨编写不同的测试用例 在 这里仅仅需要输入不同的数值即可 试试 如果出现问题 将如何解释 提示提示 控制台中的所有输入都被认为是字符 回车键是一个或两个字符 不同的操作系统和编译器有不同的解释 而在 Windows 控制台中回车键的 ASCII 码为 10 查看 atoi 的使用方法 注意它执行失败后的返回值 为什么将 d 改为 c 即可避免死循环 大家知道 V0 1 版本出现死 循环的原因完全是因为 scanf 从缓冲区读取值失败所引起的 因为在输入输出 流中所有的类型都会被当作字符来看待 那么当使用 c 来读入 chCmd 时 不 管输入什么样的值都会成功 当 scanf 成功之后 则会将缓冲区中的字符清空 实际上是将 流指针 后移 等待下一次用户的输入 所以它不会出现死循 环 2 方法方法 2 既然问题是由用户输入函数带来的 那么我们即可使用其它标准库函数来 解决这个问题 根据控制台菜单程序用户输入的特点 我们不妨输入单字符来 触发功能 即通过 getchar 函数来实现用户交互 但是 我们一定要注意其中 的细节 该函数的原型 int getchar void 在常见的 c 编译器里面 char 类型取值范围为 128 127 类似 EOF 等宏 的值则在此取值范围之外 那么 EOF 将不会被正确地读入 那么 char c getchar 则是一个隐藏很深的 bug 在这里我们将接受输入值的变量定义为 int 程序清单 2 用 if else 做分支处理并用字符作比较 V0 2 void CmdRunning int iCmdNum 0 do printf 请选择 0 退出 1 新建文件 2 打开文件 3 保存文件 n iCmdNum getchar fflush stdin 清空缓冲区 if 0 iCmdNum printf 谢谢使用 再见 n else if 1 iCmdNum CreateFile else if 2 iCmdNum OpenFile else if 3 iCmdNum SaveFile else printf 对不起 你选择的数字不存在 请重新选择 n while 0 iCmdNum 下文预告下文预告 由于 If else 方式在处理多分支时显繁琐并且效率低效 它必须一个一个分支地判断 而处理多分支比较容易想到的就是 switch 语句了 为了避免出现 V0 1 版本中的死循环 我们后面的例子将使用另外一个输入函数 控制台菜单选项的实现 控制台菜单选项的实现 1 使用使用 if else 入门入门 2010 09 22 21 15 30 转载 标签 缓冲区 多分支 控制台菜单选项 教育 声明 在这一个系列中本着一题多解 步步深入以及尽量降低初学者的阅读 难度减少枝叶代码的精神 很多细节都没有处理 例如举的例子中的函数的返 回值都是 void 函数中间没有安全检查 及其它的一些问题 通过例子中的几 十行代码不可能做的面面俱到 在实际编程中是不能这样的 请同学们不要盲 目效仿 要想成为一名优秀的软件工程师 你必须对自己的代码精益求精 哪怕是最 简单的问题也需要仔细考虑 在尽量减少 Bug 出现的可能性的同时还需要提高 程序的扩展性 下面就举一个大家认为很简单 也非常熟悉的一个控制台菜单 选项程序 第一个版本 V0 1 使用 if else 做分支 这个可能是初学者最先想到的方式 程序清单 1 用 if else 作分支处理 V0 1 void CmdRunning int iCmdNum do printf 请选择 0 退出 1 新建文件 2 打开文件 3 保存文件 n scanf d if 0 iCmdNum printf 谢谢使用 再见 n else if 1 iCmdNum CreateFile else if 2 iCmdNum OpenFile else if 3 iCmdNum SaveFile else printf 对不起 你选择的数字不存在 请重新选择 n while iCmdNum 0 细心的同学可能会发现 这段程序存在一个很严重的 Bug 比如 运行程序 后输入字符 a 非数字 回车 死循环出现了 为什么会出现这种情况呢 原因是 scanf 只能将缓冲区中的数字 使用了 d 读入 iCmdNum 并清空缓 冲区 而我们输入的是非数字 那么 scanf 读入失败 失败了它也就不会去清 空缓冲区 这样造成的结果就是 我们不需要再输入其它字符 scanf 每次都 会去读缓冲区 每次都失败 每次都不会清空缓冲区 当下次再来读时发现缓 冲区中有数据就不会停止等用户输入 接着又进入下一次的循环 死循环就形 成了 祝大家中秋快乐 我的一位朋友给我的短信 祝中秋乐在工作中 于是发 了这篇博文 对于初学者来说 这是一篇非常好的系列训练材料 2010 年 9 月 22 日 变量的定义与声明 变量的定义与声明 1 2010 08 27 11 40 51 转载 标签 变量 常量 编译器 标识符 内存地址 教育 2 2 2 2 2 2 变量的声明与定义变量的声明与定义 V0 3 V0 3 1 变量的定义变量的定义 从前面的章节可以看出 程序中所有的东西几乎都有名字 然而字面量却是个例外 它没有名字 那么使用变量 我们就可以为某个值取名字了 实际上 我们是为系统内存 中用于保存数据的某块空间取名字 ANSI C 规定 变量必须 先定义 后使用 因此当用 C 定义变量时 不仅需要指 定变量名 而且还必须告诉编译器其存储的数据类型 变量类型告诉编译器应该在内存中 为变量名分配多大的存储单元 用来存放相应变量的值 变量值 而变量仅仅是存储单 元的别名 供变量使用的最小存储单元是字节 Byte 由此可见 每个变量都占据一个特定的位置 每个存储单元的位置都由 地址 唯一 确定并引用 就像一条街道上的房子由它们的门牌号码标识一样 即从变量中取值就是通 过变量名找到相应的存储地址 然后读取该存储单元中的值 而写一个变量就是将变量的 值存放到与之相应的存储地址中去 由于变量的定义不是可执行代码 因此要求局部变量的定义必须位于用 包围的程包围的程 序块序块 的开头 即在可执行代码的前面 比如 int LowerLimit 80 定义 LowerLimit 为整型变量 即在定义 LowerLimit 为 int 类型数据时 系统就已经为变量 LowerLimit 分配了存储单元 请注意区分变量名和变量值这两个不同的概念 其中 LowerLimit 为变量名 80 为变量 LowerLimit 的值 即存放在变量 LowerLimit 的存储单元中的数据 那么到底如何获得变量的地址呢 C 语言使用 但如果将一个定义语句中的多个变量拆开在多个定义语句中定义的话 int LowerLimit LowerLimit 为数据下限 int UppeLimit UpperLimit 为数据上限 int sum sum 为求和的结果 则可在各个定义语句中添加注释 则大大提高了程序的可阅读性 而且修 改起来更加方便 但 C 编译器会忽略在每行右边用于描述变量用途的注释语句 与此同时还可以在定义中 对变量进行初始化 即允许在变量名的后面紧跟一 个等号以及一个表达式 int LowerLimit 1 intUpperLimit LowerLimit 50 intsum 2 外部变量的声明外部变量的声明 由于变量 LowerLimit是在别的文件中定义的 那么只要在引用之前用关键字 extern 对该变量作 外部变量声明 即可 无需再为变量 LowerLimit分配存储单 元 这种情况称之为声明或引用性声明 比如 extern int LowerLimit 将已定义的外部变量 LowerLimit 的作用域扩展到此 在这里将 extern 置于变量前 就是为了告诉编译器变量 LowerLimit 这个名 字已经在别的文件中被定义了 因此遇到此变量时 需在其它模块中寻找与之 相应的定义 有时程序是由多个源程序文件组成的 那么只需要在其中任一个文件中定 义外部变量 LowerLimit 而在另一
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 部门级安全培训课件
- 部门安全日常培训内容课件
- 避免革命的改革课件
- 交通韧性评估国际标准对比-洞察及研究
- 基于循环经济的2-氨基-4-氯苯酚生产废料资源化利用模型
- 国际面粉切割标准与本土饮食习惯差异的适配性研究
- 国际标准对接中凹凸管流体力学性能测试方法与ISO认证路径探索
- 可变拓扑结构分装设备应对突发性订单波动的响应机制
- 双螺杆减速与柱塞泵协同传动的能量损耗耦合优化策略
- 双相钢热处理工艺参数与齿轮副接触应力场的动态匹配难题
- 消除三病反歧视培训
- 脑转移瘤的治疗进展
- 脚手架工安全技术交底(完整版)
- 接触网运行与检修 课件全套 薛艳红 第1-9章 电气化铁道概述-高速铁路接触网精测精修
- 2024-2030年中国抗衰老产品和服务行业市场发展趋势与前景展望战略研究报告
- 酒店实美学 课件全套 杨卉 第1-13章 酒店美学概述-酒店服务之美
- 聚焦高质量+探索新高度+-2025届高考政治复习备考策略
- 甲醇含量测定方法
- 【基于危险预知训练方法的安全实践探究12000字(论文)】
- 《智慧农业关键技术与装备》课件-第11章 农业预测预警
- 电工仪表与测量(第六版)中职技工电工类专业全套教学课件
评论
0/150
提交评论