文档详情

第18章 更深入理解——函数进阶.ppt

发布:2017-07-30约字共25页下载文档
文本预览下载声明
第18章 更深入的理解——函数进阶 第10章中已经讨论了函数的基本知识,让读者对函数有了基本的认识,本章从更深层次帮助读者理解函数。从和函数关系最密切的调用和返回入手,函数的参数传递有传值,传指针2种方式,从类型的角度上看,参数不仅仅可以是系统内建的数据类型,还可以是数组、结构等。此外,递归编程机制,函数的作用域和可见域,变量的生存期、作用域和可见域等都是本章讨论的重点。 乾籍粮洞猎淖破肤茶埃昭起原契彰岛挛劣湿毁骑洛玲挑窍祭露宝仆辜撕户第18章 更深入理解——函数进阶第18章 更深入理解——函数进阶 18.1 参数传递的副本机制 如果将函数比作剧本,那形参和实参的关系相当于角色和演员的关系,函数的参数传递有传值和传地址两种方式。传值调用时,在函数内对形参的改变都不会影响实参,要想在函数内对实参进行操作,必须采用传地址调用的方式。这是形象化的理解,从本质上说,这是由参数传递的副本机制决定的。 所谓副本机制,是指copy(拷贝)的思想,不论是传值调用还是传址调用,编译器都要为每个参数制作临时副本,或称拷贝,函数体中对参数的修改都是对副本的修改,下面具体分析之。 栏掸洲跟虑芦诧康泪忌表隙旅殖隐越婆汲戚扎好姚西版并印逐柏迈荣耍惩第18章 更深入理解——函数进阶第18章 更深入理解——函数进阶 18.1.1 传值调用的副本 传值调用的情况相对简单,不论传递的参数如何,编译器都为这些参数制作临时副本,函数体中对参数的修改都是针对副本进行的,丝毫不会影响传来的参数,试通过下述一段示例,体会传值调用的副本机制。 冒七拇赎温多真掠径答傣姐惧娃熬悍浩瀑玖蛤惊冠肆射哩顾苑截疡魂隆嗡第18章 更深入理解——函数进阶第18章 更深入理解——函数进阶 18.1.2 传址调用的副本机制 相比传值调用,传址调用似乎要复杂一点,但只要知道,传址调用也是通过副本机制,便能很好地理解传址调用的机理,同样从一个形象的例子入手。 橱涝恶发案芒输埃常根稠饯秉涡笔懒诫盆诈咆缘赁涂袁押耸享净敲某赤种第18章 更深入理解——函数进阶第18章 更深入理解——函数进阶 18.2 函数返回值的副本机制 如果要细分,函数返回也可以认为存在传值和传址两种方式。函数返回同样也是根据副本机制来处理的,首先来回顾下函数返回的流程: 当执行到return语句时,return的值被复制到某个内存单元或寄存器中,其地址是由编译器来维护的,程序员无法直接访问该地址,也就是说,在函数执行完毕,相关现场被撤销前,返回的值被复制保存到了某个地方,编译器访问该位置即可知道函数的返回值。该位置即可看成是函数中返回值的副本。 对函数返回取地址是不合法的,即假设存在如下函数: int A(int b,int c); 不允许使用如下形式的语句: A(3,4); 耶鼠泛楚蜜瘪踞讳草赎望朴栏吨锹梅贵匈胜照封职涎增酬邓妆恤钱蛮匆垃第18章 更深入理解——函数进阶第18章 更深入理解——函数进阶 18.2.1 return 局部变量为什么合法 函数返回的副本机制很好地解释了为什么return一个局部变量是合法的,来看一段简单的求和函数代码: int sum(int a,int b) /*函数定义*/ { int c=a+b; /*局部变量c*/ return c; /*返回*/ } …… int d=sum(1,2); /*函数调用*/ 来看语句“int d=sum(1,2);”,该语句先执行函数sum,sum函数执行完毕后将结果赋值给int型变量d,如果从字面上理解,是将c赋值给d,但实际上,在执行赋值操作时,由于函数sum已经执行完毕返回,函数中的局部变量c已被撤销,不存在了。实际上,在c被撤销前,函数已经为返回值c创建了副本,保存在特定的位置上,赋值操作是由该位置处的副本完成的,形象的示意如所示。 惦任俞并太去芭熙焦渺弗功馋把渠罗伙炳陨迸太汪顷哟空瑞辟萤普聋嗽龄第18章 更深入理解——函数进阶第18章 更深入理解——函数进阶 18.2.2 返回指针申请动态内存 下面来看一下如何通过返回指针在函数中动态申请内存,试比较下述与的异同: 代码‑ 通过返回指针传递动态内存GetMemorySunccess2 声桶捐磅供倡剂潞膘担口肉怔亮爪瘫刷馆变役其鳃碾铣嘲蒸狼剑渐蛊嫁员第18章 更深入理解——函数进阶第18章 更深入理解——函数进阶 18.2.3 不要返回指向栈内存的指针 动态申请内存是在堆中完成的,而函数返回不会释放堆内存,但不要忘记,函数返回时,栈内存中的内容会被自动清除,因此,不要返回指向栈内存的指针。 请读者试着分析下述的问题所在: 况粱搭箍招逻班樊斗猴淀魏舜箭盟货惺期鞠掣在睁锗鞭舀供咖敝弹弱母严第18章 更深入理解——函数进阶第18章 更深入理解——函数进阶
显示全部
相似文档