




已阅读5页,还剩54页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1 第6章函数与预处理命令 江汉大学数计学院 C语言程序设计 2 第6章函数与预处理命令 6 1概述6 2函数的定义与调用6 3函数的嵌套调用和递归调用6 4局部变量和全局变量及其作用域6 5变量的存储类别及变量的生存期6 6编译预处理 3 6 1概述 程序结构清晰 可读性好 减少重复编码的工作量 可多人共同编制一个大程序 缩短程序设计周期 提高程序设计和调试的效率 使用函数的好处 4 例6 1 求一个整数的立方 intcube intx 函数定义 return x x x main intf a printf nEnteranintegernumber scanf d 程序运行情况如下 Enteranintegernumber 2 2 2 2 8 函数调用 程序的执行总是从main函数开始 5 一个C源程序可以由一个或多个源程序文件组成 C编译系统在对C源程序进行编译时是以文件为单位进行的 一个C源程序文件可以由一个或多个函数组成 所有函数都是独立的 主函数可以调用其它函数 其它函数可以相互调用 在一个C程序中 有且仅有一个主函数main C程序的执行总是从main函数开始 调用其它函数后最终回到main函数 在main函数中结束整个程序的运行 说明 6 函数的种类 从函数定义形式分 有参函数在主调 用 函数和被调 用 函数之间通过参数进行数据传递 如 intcube intx 无参函数如 getchar 在调用无参函数时 主调函数不需要将数据传递给无参函数 从使用的角度看 标准函数 库函数 库函数是由系统提供的 如 getchar sin x 等 在程序中可以直接调用它们 附录A列出了C的部分库函数 用户自定义函数如 例6 1中的cube函数 7 例6 2 无参函数的定义与调用 voidwelcome printf n printf WelcometoChina n printf n main welcome 程序的输出结果如下 WelcometoChina 8 6 2 1函数的定义 函数定义的一般形式 函数类型函数名 类型名形式参数1 说明语句执行语句 例如 求两个数的最大值 intmax intx inty intz z x y x y return z 类型省略时默认为int类型 9 intmax x y intx y intz z x y x y return z intmax x y intx y 或intmax intx y 或intmax x y intx y z z x y x y return z 花括号中也可以为空 这种函数叫空函数 例如 null 不能在函数体内定义其他函数 即函数不能嵌套定义 形参也可以这样定义 10 函数名 实参表列 在C语言中 把函数调用也作为一个表达式 因此凡是表达式可以出现的地方都可以出现函数调用 例如 welcome if iabs a max max iabs a m max c max a b 6 2 2函数的调用 函数调用的一般形式 11 intsum inti t 0 for i 1 i 100 i t i return t main ints s sum printf d n s 程序输出结果 5050 intsum intx inti t 0 for i 1 i x i t i return t main ints s sum 100 printf d n s 例6 3 求1 100的累加和 思考 两个程序有何不同 程序输出结果 5050 12 voidswap intx inty intz z x x y y z printf nx d y d x y main inta 10 b 20 swap a b printf na d b d n a b 6 2 3函数参数与函数的返回值 1 函数的形式参数与实际参数 程序输出结果 x 20 y 10a 10 b 20 形式参数 形参 实际参数 实参 例6 4 编一程序 将主函数中的两个变量的值传递给swap函数中的两个形参 交换两个形参的值 单向值传递 13 形参和实参 swap函数在调用时 形参x y才被分配存储空间 从main函数中分别获实参传递的值10 20 此为虚实结合 voidswap intx inty intz z x x y y z printf nx d y d x y main inta 10 b 20 swap a b printf na d b d n a b 14 有关形参和实参的说明 当函数被调用时才给形参分配内存单元 调用结束 所占内存被释放 实参可以是常量 变量或表达式 但要求它们有确定的值 实参与形参类型要一致 实参与形参的个数必须相等 在函数调用时 实参的值赋给与之相对应的形参 单向值传递 15 例6 5 函数调用中实参的求值顺序 voidfun inta intb printf a d b d n a b main intm 5 fun 3 m m 程序输出结果 a 8 b 5 16 2 函数的类型与函数的返回值 说明 函数的类型决定了函数返回值的类型 若省略函数的类型 系统默认其为int型 无返回值的函数应将其类型定义为void 空 类型 函数的类型 例6 6 输出两个数中的大数 max intx inty intz z x y x y return z 返回z的值 main inta b c scanf d d 17 函数的返回值是通过return语句带回到主调函数的 功能 终止函数的运行 返回主调函数 若有返回值 将返回值带回主调函数 说明 若函数没有返回值 return语句可以省略 return语句中的表达式类型一般应和函数的类型一致 如果不一致 VC系统警告的同时自动将表达式类型转换为函数类型 函数的返回值 return语句格式 return 表达式 return表达式 return 18 例6 8 计算并输出圆的面积 s intr return3 14 r r main intr area scanf d 自动转换为int型 思考 若要得到单精度实型的圆面积 程序应如何修改 程序运行情况如下 2 12 19 6 2 4对被调函数的声明和函数原型 变量要先定义后使用 函数也如此 即被调函数的定义要出现在主调函数的定义之前 如swap函数 允许整型函数 且参数也是整型 的定义出现在主调函数之后 如max函数 如果非整型函数在主调函数之后定义 则应在主调函数中或主调函数之前对被调函数进行声明 voidswap intx inty main swap a b main c max a b max intx inty 20 对被调用函数的说明 如果使用库函数 应在文件开头用 include命令将调用库函数所需的信息包含到文件中来 如 include stdio h stdio h是开头文件 其中存放了I O库函数所用到的一些宏定义信息 include math h 使用数学库函数应用这条命令 如果使用用户自己定义的函数 一般应在主调函数中对被调用函数作类型说明 main floatadd floatx floaty floata b c scanf f f floatadd floatx floaty 21 对被调函数进行声明的一般形式 函数类型函数名 参数类型1参数名1 或函数类型函数名 参数类型1 参数类型2 思考 以下哪种情况需要在主调函数中对被调函数声明被调函数定义在前 主调函数定义在后 主调函数定义在前 被调函数定义在后 且被调函数的类型不是整型的 被调函数定义在后 但被调函数的类型是整型 第二种形式省略了参数名 此种形式也称为函数的原型 22 6 3函数的嵌套调用和递归调用 main函数 调用函数A 函数A 调用函数B 函数B 6 3 1函数的嵌套调用 23 例6 15 函数的嵌套调用 main intn 3 printf d n sub1 n sub1 intn inti a 0 for i n i 0 i a sub2 i returna sub2 intn returnn 1 程序输出结果 9 24 6 3 2函数的递归调用 1 递归的基本概念 递归调用 一个函数直接或间接地调用了它本身 就称为函数的递归调用 递归函数 在函数体内调用该函数本身 intsub intx inty z if z sub y else return 例如 直接调用sub函数本身 25 2 递归函数的执行过程 例6 16 编一递归函数求n 思路 以求4的阶乘为例 4 4 3 3 3 2 2 2 1 1 1 0 1 递归结束条件 当n 1或n 0时 n 1 递归公式 26 程序如下 floatfact intn floatf 0 if n 0 printf n 0 error elseif n 0 n 1 f 1 elsef fact n 1 n return f main intn floaty printf nInputn scanf d 运行情况如下 Inputaintegernumber 4 4 24 27 递归调用过程 28 6 4局部变量和全局变量及其作用域 6 4 1变量的作用域 6 4 2局部变量及其作用域 变量的作用域 变量在程序中可以被使用的范围 根据变量的作用域可以将变量分为局部变量和全局变量 局部变量 内部变量 在函数内或复合语句内定义的变量以及形参 作用域 函数内或复合语句内 例6 19 分析下面程序的运行结果及变量的作用域 问题 一个变量在程序的每个函数中都能使用吗 29 voidsub inta intb intc a a b b b a c b a printf sub ta db dc d n a b c main inta 1 b 1 c 1 printf main ta db dc d n a b c sub a b printf main ta db dc d n a b c inta 2 b 2 printf comp ta db dc d n a b c printf main ta db dc d n a b c 程序输出结果 main a 1b 1c 1sub a 2b 3c 1main a 1b 1c 1comp a 2b 2c 1main a 1b 1c 1 30 6 4 3全局变量及其作用域 全局变量 外部变量 在函数外部定义的变量 作用域 从定义变量的位置开始到本源文件结束 如在其作用域内的函数或分程序中定义了同名局部变量 则在局部变量的作用域内 同名全局变量暂时不起作用 例6 20 全局变量和局部变量的作用域 31 inta 5 voidf intx inty intb c b a x c a y printf d t d t d n a b c 程序输出结果 511 2567987981098105610 全局变量 32 6 5变量的存储类别及变量的生存期 6 5 1变量的生存期与变量的存储分类 变量的生存期 变量在内存中占据存储空间的时间 思考 1 何时为变量分配内存单元 2 将变量分配在内存的什么区域 3 变量占据内存的时间 生存期 动态存储变量 静态存储变量 33 6 5 2变量的存储类别 变量的属性 数据类型 决定为变量分配内存单元的长度 数据的存放形式 数的范围 存储类别 决定了变量的生存期 给它分配在哪个存储区 34 变量定义语句的一般形式 存储类别数据类型变量名1 变量名n auto 自动的 register 寄存器的 static 静态的 extern 外部的 1 自动变量 auto类别 局部变量可以定义为自动变量 35 内存分配调用函数或执行分程序时在动态存储区为其分配存储单元 函数或分程序执行结束 所占内存空间即刻释放 变量的初值定义变量时若没赋初值 变量的初值不确定 如果赋初值则每次函数被调用时执行一次赋值操作 生存期在函数或分程序执行期间 作用域自动变量所在的函数内或分程序内 自动变量 36 2 静态变量 static类别 除形参外 局部变量和全局变量都可以定义为静态变量 37 内存分配编译时 将其分配在内存的静态存储区中 程序运行结束释放该单元 静态变量的初值若定义时未赋初值 在编译时 系统自动赋初值为0 若定义时赋初值 则仅在编译时赋初值一次 程序运行后不再给变量赋初值 生存期整个程序的执行期间 作用域局部静态变量的作用域是它所在的函数或分程序 全局静态变量的作用域是从定义处开始到本源文件结束 静态变量 38 intc staticinta main floatx y chars f staticintb 1 3 外部变量 extern类别 在函数外定义的变量若没有用static说明 则是外部变量 外部变量只能隐式定义为extern类别 不能显式定义 39 内存分配编译时 将其分配在静态存储区 程序运行结束释放该单元 变量的初值若定义变量时未赋初值 在编译时 系统自动赋初值为0 生存期整个程序的执行期间 作用域从定义处开始到本源文件结束 此外 还可以用extern进行声明 以使其作用域扩大到该程序的其它文件中 外部变量 问题 全局静态变量的作用域可以扩展到本程序的其它文件吗 40 外部变量声明的一般格式 extern数据类型变量名1 变量名n 或extern变量名1 变量名n 注意 外部变量声明用关键字extern 而外部变量的定义不能用extern 只能隐式定义 定义外部变量时 系统要给变量分配存储空间 而对外部变量声明时 系统不分配存储空间 只是让编译系统知道该变量是一个已经定义过的外部变量 与函数声明的作用类似 41 intp 1 q 5 floatf1 inta externcharc1 c2 charc1 c2 charf2 intx inty main 思考 在f1函数中声明c1 c2的作用是什么 如何修改程序使所有函数都可以使用外部变量而又不需要声明 例6 24 在一个文件内声明外部变量 42 例6 25 在多文件的程序中声明外部变量 file1 c文件中程序如下 inti main voidf1 f2 f3 i 1 f1 printf tmain i d i f2 printf tmain i d i f3 printf tmain i d n i voidf1 i printf nf1 i d i file2 c文件中程序如下 externinti voidf2 inti 3 printf nf2 i d i voidf3 i 3 printf nf3 i d i 程序输出结果 f1 i 2main i 2f2 i 3main i 2f3 i 3main i 3 声明外部变量 定义外部变量 43 4 寄存器变量 register类别 只有函数内定义的变量或形参可以定义为寄存器变量 寄存器变量的值保存在CPU的寄存器中 受寄存器长度的限制 寄存器变量只能是char int和指针类型的变量 例7 26 寄存器变量的使用 main longintsum 0 registerinti for i 1 i 1000 i sum i printf sum ld n sum 程序输出结果 sum 500500 44 6 5 3归纳变量的分类 1 按照变量的作用域对变量分类 局部变量 全局变量2 按照变量的生存期对变量分类 静态存储变量包括 局部静态变量和全局静态变量 动态存储变量包括 自动变量 45 源文件 c 运行文件 exe 目标文件 obj 编译 连接 编译预处理包括 宏定义文件包含条件编译 6 6编译预处理 46 6 6编译预处理 续 main floatr s c scanf f 如何修改圆周率 47 define宏名字符串 宏定义的功能 在进行编译前 用字符串原样替换程序中的宏名 这个替换过程称为 宏替换 或 宏展开 字符串也称为替换文本 命令的一般格式 6 6 1不带参数的宏定义 6 6编译预处理 续 48 6 6编译预处理 续 例如 definePI3 14main floatr s c scanf f 替换 3 14 3 14 编译 49 6 6编译预处理 续 为了增加程序的可读性 建议宏名用大写字母 其他的标识符用小写字母 双引号中有与宏名相同的字符串不进行替换 已经定义的宏名可以被后定义的宏名引用 在预处理时将层层进行替换 说明 宏定义的作用域是从定义处开始到源文件结束 但根据需要可用undef命令终止其作用域 形式为 undef宏名 50 例6 29 不带参数的宏定义 源程序 definePI3 14 defineSPI r r defineV4 S r 3main floatr printf nInputr scanf f 编译预处理后的程序 main floatr printf nInputr scanf f S V 51 命令的一般形式 6 6 2带参数的宏定义 define宏名 形参表 字符串 功能 在编译预处理时 把源程序中所有带参数的宏名用宏定义中的字符串替换 并且用宏名后圆括号中的实参替换字符串中的形参 例如 defineMAX X Y X Y X Y 6 6编译预处理 续 52 6 6编译预处理 续 例6 30 带参数的宏定义 defineMAX x y x y x y main printf d n a b MAX a b printf d n MAX a m b n 分两次替换 将宏名MAX a b 替换成字符串 x y x y 用实参a替换形参x 实参b替换形参y 程序中的两个printf语句被展开为 printf d n a b a b printf d n a m b n a m b n 53 6 6编译预处理 续 例6 31 分析下面程序运行后的输出结果 defineMA x x x 1 main inta 1 b 2 printf d n MA 1 a b 分两次替换 MA 1 a b 用x x 1 替换 用1 a b替换x printf语句被展开为 printf d n 1 a b 1 a b 1 特别注意 由于替换文本中的x没有用括号括起 因此 1 a b也不能用括号括起 程序输出结果 8 54 6 6编译预处理 续 命令的一般形式格式1 include格式2 include 文件名 6 6 3文件包含 文件包含是
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年企业人力资源管理师(人力资源薪酬福利管理师级)技能操作试卷
- 南京师范大学中北学院《油画(二)写生》2024-2025学年第一学期期末试卷
- 荆州理工职业学院《非参数统计》2024-2025学年第一学期期末试卷
- 西南政法大学《中学政治课教材分析》2024-2025学年第一学期期末试卷
- 湖南师范大学树达学院《专修足球(2)》2024-2025学年第一学期期末试卷
- 2025年护士执业资格考试护师考试模拟题及解析
- 2025年燃气储运行业趋势分析与初级考试预测题解析
- 江西农业大学南昌商学院《实验动物解剖学》2024-2025学年第一学期期末试卷
- 山西工程科技职业大学《生物工程专业大》2024-2025学年第一学期期末试卷
- 2025年殡葬行业职业认证与考试信息解读
- 光伏居间的合同8篇
- GB/T 45418-2025配电网通用技术导则
- 医疗风险防控培训课件
- 机械设计部绩效考核制度
- 诊疗规范培训课件
- 《KANO模型培训》课件
- 复苏室患者的交接流程
- 【人教版化学】选择性必修1 知识点默写小纸条(答案背诵版)
- DB21-T 2523-2015矿山地质环境恢复治理规程
- 新能源集控中心建设方案
- 《中国老年糖尿病诊疗指南(2024版)》解读课件
评论
0/150
提交评论