第5章 函数

5 函数

5.1函数的性质

1 a)函数可以有参数有返回值,可以没参数有返回值,可以有参数没有返回值,也可以无参数无返回值,表现的像一个过程。

b)函数具有独立性,一个函数内不能定义另一个函数,所以不存在子函数的概念。

2 函数参数靠传值机制实现,传值即在函数被调用时,用克隆实参的办法来创建形参,而实参本身不发生改变。传值时,实参和形参类型应该匹配或者能隐式类型转换。

void f2(int b){};

void f3(int* c){};

void f4(int& d){};

int main()

{

       f2(2.5);

       f2('c');

       int e = 3;

//     f3(e); //error C2664: 'f3' : cannot convert parameter 1 from 'int' to 'int *'

       f3(&e);

       f4(e);

//     f4(&e); //error C2664: 'f4' : cannot convert parameter 1 from 'int *' to 'int &'

       return 0;

}

3 运行时内存

代码区

程序代码

全局数据区

全局数据、常量、文字量、静态全局量、静态局部量

动态内存

函数数据区(局部数据区)

4 局部数据的不确定性

原因:os为函数分配的栈空间当被使用再回收之后,并没有被清扫,当再次非配给局部变量时,其中的数值是不确定的。

5函数指针

1int *gp(int); //声明一个指针函数

     int (*gp)(int); //定义一个函数指针,其类型为:int (*) (int)

(1)函数指针的初始化方式:

A.     int g(int); int (*gp)(int) = g; //定义时初始化 B. int (*gp)(int); gp = g; 先定义后赋值。

(2)声明一个函数指针类型

Typedef int (*Fun)(int a,int b); int m(int,int); Fun funp = m;

(3)typedef int Func(); // 将函数类型称为Func

此时函数指针可以定义为: Func * pf;

int (*func(int)) (); // 为一个函数声明,声明*func(int) int ()型,等同于: Func * func(int);

它是返回一个函数指针的带int 型参数的函数声明,其返回的函数指针类型为int().

Typedef int (* SIG)();

Typedef int(* SIGARG)(); //声明函数指针

SIG signal(int , SISGARG);//声明的函数返回函数指针,其参数为整型和函数指针

(1)   如果函数参数中出现了函数类型,则自动转换为函数指针,这种现象叫做蜕变(decay.

(2)    

如:MenuFun fun[] = {f1,f2}; 即是蜕变的形式,本应为MenuFun fun[] = {&f1,&f2};

其函数调用的形式为fun[0](),本应为*fun[0]();

同理可以使用函数引用 :

Void g(); typedef void Fun(); Fun & f=g; f();//????

(3)   函数指针的作用:

a)       调用其他语言的函数或过程

b)      通过动态链接库的形式访问其他的进程

c)       函数指针作为参数,当参数取不同的值时,可以使函数表现出不同的形式。

6 命令行参数

使用标准输入输出设备的程序可以重定向输入输出方式。

可重定向的程序的的好处是可以在运行时临时决定输入输出的方式

不专门指定设备时默认为标准输入输出,否则<’后面规定输入设备,‘>’后面规定输出设备。‘》’以追加的形式输出到输出设备。

#include<iostream>

using namespace std;

int main()

{

       for(int a, int b; cin>>a>>b; cout<<a+b<<endl);

       return 0;

}

默认为标准输入输出。

在命令行输入命令:

D:/> redirect <abc.txt  >xyz.txt

表示运行redirect程序时的输入设备为abc.txt ,输出设备为xyz.txt

D:/> redirect <abc.txt  >>xyz.txt 表示以追加的方式输出到xyz.txt

7 使用main函数

当程序要处理的是若干个非标准设备的资源文件,或者遵循某种形式的命令时,可以使用main函数的参数。

Int main(int argc, char** argv)

其中argc 为参数的个数,argv为参数数组。argv 为一个c串数组,类型为char** 数组的最后一项为空串

Argv 的出现形式可以是:程序待处理的字符、输入输出文件名、命令等。

注意: 所运行的程序的名称也是argv中的一个参数。

 

8         递归函数

(1)递归条件:

A.有停止条件,即递归函数中有完成终极任务的语句序列。Eg.if(n==1) return 1;

B. 递归条件应该先测试,后递归调用。

(2)递归评说

递归的好处的是便于设计程序、简单易读,不利之处是它增加了系统的时间、空间开销:在时间上,执行函数的调用和返回要大于非递归函数;在空间上没递归一次便增加一段栈开销,影响程序性能。

9函数重载

(1)   C++在调用重载函数时的顺序是:1)寻找严格匹配2)通过相容 类型的隐式转换匹配3)通过用户定义的转换匹配。

(2)   void print(long a){cout<<a<<endl;}

void print(double a){cout<<a<<endl;}

              print(a); //error C2668: 'print' : ambiguous call to overloaded function

(3)   c++函数重载技术的实现:利用函数名压轧技术来改变函数名,区分参数不同的同名函数。例如 void fun(char a,int b,double c); 被压轧为fun_cidfun_c_i_d(不同编译器实现不同)

10默认参数

1)默认规则:

a)默认参数只能在函数声明或定义中出现一次,不能在两者中同时出现。通常情况下,默认参数应放在声明中。

b)默认参数只能从后往前设置

eg.void func(int a=1, int b, int c=3, int d=4); // missing default parameter for parameter 2

  void func(int a, int b=2, int c=3, int d=4); //ok

默认参数的替换也只能从后往前逐个替换尾部的“缺陷”

Func(); //error

Func(12,12); //ok, cd默认

Func(2,15, , 20);//error,d不默认,c也不能默认

11 重载还是参数默认

A)     如果两个函数做基本相同的事,只不过参数个数不同,则适合于用参数默认

Eg. Void decay(); void decay(int a );

可以将两者重载,也可以先定义后者,再重载decay():

Void decay(){decay(2);},最好的方法是利用参数默认:void decay(int a = 2){}.

B)     如果一个参数的值用来确定不同的操作,则适合用重载。

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值