C02-语法基础4.ppt_第1页
C02-语法基础4.ppt_第2页
C02-语法基础4.ppt_第3页
C02-语法基础4.ppt_第4页
C02-语法基础4.ppt_第5页
已阅读5页,还剩41页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、C+基础语法4函数,函数的概述 函数的定义 函数的使用 变量的存储管理,函数的概述,源文件由若干函数组成 平行结构 函数的分类 函数的定义和声明 程序入口 main,winmain,dllmain,C+运行时库,msvcrt.dll(名称:Microsoft C Runtime Library)提供了printf,malloc,strcpy等C语言库函数,并且为使用C/C+(Vc)编绎的程序提供了初始化(如获取命令行参数)以及退出等功能.,函数调用,栈 过程活动记录 形实结合 局部变量 代码运行 函数返回值,函数调用约定,stdcall(pascal调用约定, WINAPI和CALLBACK)

2、右向左压入堆栈 cdecl右向左压入堆栈 fastcall函数的第一个和第二个DWORD参数(或者尺寸更小的)通过ecx和edx传递,其他参数通过从右向左的顺序压栈 thiscall C+类成员函数缺省的调用约定 naked call不能用return返回返回值,只能用插入汇编返回结果。这一般用于实模式驱动程序设计,参数的传递,值传递 引用传递 传递过程中的类型转换,函数的返回值,函数的返回值通过return语句指定 函数的返回值不是void时,return后必须指定一个表达式,且必须所有的函数出口都要有一个return语句 函数的返回值是void时,return后不可以指定表达式 函数实际返

3、回值类型如果和函数原型中的不一致,则自动按照函数原型中指定的类型做转换,举例,double f() return ; /error int main() return ; /warning double f() return 5/4; / result is 1 int f() if() return 0; /warning,利用函数调用堆栈调试程序,VC环境中进入调试状态后,点击Debug工具条中倒数第二个按钮(CallStack),将会出现Stack窗口 此窗口中将会列出程序当前函数调用堆栈的情况,最后调用的函数列在最上面,点击里面的函数可以看到程序在不同函数调用点的运行状态,内联函数(内

4、置函数),何谓内联函数 编译时将代码插入到调用处,而不是跳到另一个地址 如何使用内联函数 可在函数定义或函数声明的左侧加inline 什么情况下可以使用内联函数 规模较小而又频繁调用的函数 类中定义的函数都是内联函数,函数重载,C+允许一个函数名定义多个函数,这些函数的参数个数和类型不同,这就是函数重载 C+不允许多个函数名字和参数表相同,而返回值不同,函数重载举例,int max(int x,int y) return (xy)? x : y; double max(double x,double y) return (xy)? x : y; ,函数重载举例,int max(int x,in

5、t y) return (xy)? x : y; int max(int x,int y,int z) x= (xy)? x : y; x= (xz)? x : z; return x; ,有默认参数的函数,在函数声明时,可以为参数指定默认值 函数的默认参数必须放在参数表的最后 在一个文件中,参数的默认值不能重复指定 有默认参数的函数不能和其它重载函数出现二义性,如: char* TrimLeft(char* sz,char ch= ); char* TrimLeft(char* sz);,默认参数举例,char* TrimLeft(char* sz,char ch= ); int main(

6、) cout TrimLeft( fdsds); cout TrimLeft(00123,0); return 0; char* TrimLeft(char* sz,char ch) int i=0; while(szi+=ch) ; return sz+i-1; ,函数的嵌套调用,函数不允许嵌套定义 函数可以嵌套调用,嵌套的层数只受栈区空间的限制 函数调用之前必须有函数的定义或声明,弦截法求方程,方程:f(x)=x3-5x2+16x-80=0 算法: 1. 不同点x1,x2;分别计算f(x1),f(x2), 如果f(x1)和f(x2)符号相反,说明x1,x2之间必有一个根。 2. 连接(x1

7、,f(x1),(x2,f(x2)这个两个点交于X轴,交点的x坐标为: x=(x1*f(x2)-x2*f(x1)/(f(x2)-f(x1);,弦截法求方程,3. 如果f(x)与f(x1)同符号说明根在(x,x2)之间,此时x作为新的x1;如果f(x)与f(x2)同符号说明根在(x1,x)之间,此时x作为新的x2 4. 重复2,3直到f(x)10-6 程序将定义两个函数f(x),root(x1,x2) f(x)代表方程式左侧多项式 root(x1,x2)代表求根函数,弦截法求方程,double root(double x1,double x2) double y1,y2,y,x; do y1=f(

8、x1); y2=f(x2); x=(x1*y2-x2*y1)/(y2-y1); y=f(x); (y*y10) ? x1:x2)=x; while (fabs(y)=1e-7); return x; ,弦截法求方程,double f(double x) return x*x*x-5*x*x+16*x-80; void main() cout root(2.5,6.7); ,函数的递归调用,问题: 求n! long fac(long n); long fac(long n) return (n=1) ? 1 : n*fac(n-1); ,函数的递归调用,用非递归方式计算n! long fac(l

9、ong n) int m=1; for(int i=1;i=n;i+) m*=i; return m; ,函数的递归调用,函数过程中又出现直接或间接地调用函数本身,称为递归调用 每次执行递归函数代码时,代码相同,但运行状态不同 可读性好,但效率低,汉诺塔问题,问题:64个盘子从A移到C,每次自允许移动一个,3个座上始终保持大的盘子在下面,移动时可以使用B座。,汉诺塔问题,先考虑最简单的情况只有两个盘子的情形:A-B,A-C,B-C 把上N-1个盘子当作一个盘子看,问题则转变成把N-1个盘子移到B,再把第N个盘子移到C,再把N-1个盘子移到C。 移动N-1个盘子和移动N个盘子的算法是一样的,而移

10、动1个盘子是没有任何问题的,这样就具备了递归的条件。,汉诺塔问题,#include using namespace std; void hanoi(int n,char b1,char b2,char b3); void main() int n; cout Please Input A number :; cin n; hanoi(n,A,B,C); ,汉诺塔问题,void hanoi(int n,char b1,char b2,char b3) if(n=1) cout b3endl; return; hanoi(n-1,b1,b3,b2); hanoi(1,b1,b2,b3); hano

11、i(n-1,b2,b1,b3); ,局部变量和全局变量,函数内部定义的变量(包括形参)称为局部变量 局部变量的作用域是所在的程序块(函数或复合语句) 在所有函数外定义的变量称为全局变量 全局变量的作用域是整个文件 不同函数中可以使用相同的变量,他们代表不同的对象,互不干扰 同一函数中的不同程序块中也可以使用相同的变量,按由内向外的规则引用。,不用全局变量的理由,1. 占用空间 2. 降低函数通用性(增加耦合度) 3. 降低程序可读性 4. 易和局部变量发生冲突,变量的存储类别,变量的存储方式 静态存储 动态存储 C/C+程序的内存管理 全局数据区(全局变量、常量、静态数据) 代码区(函数代码)

12、 栈区(函数参数、局部变量、返回值) 堆区(new/delete,malloc/free),变量的分类,自动变量(auto) 静态变量(static) 寄存器变量(register) 外部变量(extern),自动变量,自动变量指动态分配空间的变量 自动变量必须是局部变量 auto可以缺省 函数中的变量在函数调用时初始化,调用结束时释放掉 复合语句中的变量在定义时初始化,离开复合语句时释放掉,静态局部变量,函数第一次调用时做初始化,退出时变量不释放而保留原值,下次调用时不再另外初始化 静态局部变量的存储方式为静态存储,其存储空间在程序运行期间始终不释放 静态局部变量的初值如果不指定初值,则编译

13、时默认为0;而自动变量不指定初值,其值是不确定的。 静态局部变量不可在函数外被引用,举例,#include using namespace std; int f(int a) auto int b=0; static int c=3; b=b+1; c=c+1; return a+b+c; ,举例,int main() int a=2; for(int i=0;i3;i+) cout f(a) ; cout endl; return 0; 结果:7 8 9,举例,abca+b+c 1:2147 2:2158 3:2169,类的静态成员,静态数据成员不占用对象的空间,而是占用全局数据空间 静态数

14、据成员不会随对象的定义而产生,因而必须单独定义(类体外定义),且不能重复定义 访问静态数据成员有两种方式,一种和非静态成员相同;如:t.HOURS=24 另一种是:类名:静态成员 如:Time:HOURS=24; 为与非静态成员区分,建议用第二种方式,静态成员函数,格式: static 成员函数声明(类体中); 静态函数和非静态成员函数的根本区别是:静态成员函数中没有this指针,因此静态成员函数中不能通过this访问类中的非静态成员 访问静态函数和访问静态数据成员类似,可以和非静态函数相同,但最好采用 类名:函数名(实参表) 的格式,register变量,一般的变量保存在内存中。访问内存速度

15、不及直接放在寄存器中速度快。 在C中,register变量不可以取地址( ,外部变量,在一个文件中声明全局变量 extern int g_a; g_a=1; int g_a; 在多个文件中声明全局变量 在任意一个文件中定义该变量,在其他文件中用extern 声明该变量,外部变量,注意不要将外部变量的定义写在头文件中,否则引用此头文件的cpp文件将会创建不同变量,从而导致连接错误。如: f1.h: int a=1; f1.cpp:#include “f1.h” f2.cpp:#include “f1.h” 会出现连接错误: error LNK2005: int a (?a3HA) already defined in b.obj,用static 声明静态外部变量,用static 声明的全局变量不可以被其他文件使用,即便其他文件中用extern 声明了该变量,如: f1.cpp : static int a=1; f2.cpp : extern int a; ,变量属性小结,变量有三种属性 存储类别: auto,static,register,extern 作用域:可以引用改变量的区域。包括文件作用域、函数作用域、块作用域(

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论