C++学习笔记(六)

函数

函数时一个命名了的代码块,通过调用函数执行相应的代码。可以有0个或多个参数,通常会产生一个结果。

1.一个典型的函数包含了四个部分:返回类型,函数名,形参列表以及函数体。

2.函数的调用完成两项工作:一是用是参数(隐式的)初始化函数对应的形参,当调用一个函数时,首先创建一个同类型的变量a,然后将a初始化为调用时的实参;第二是将控制权从主调函数转移给被调函数。

3.实参是形参的初始值,实参的类型必须和对应的形参类型匹配。

4.名字有作用域,对象有生命周期(该对象在程序执行过程中存在的一段时间)。形参和函数体内部定义的变量成为局部变量,仅在函数的作用域内可见,同时局部变量还会隐藏在外层作用域中同名的其它所有声明

5.自动对象:只存在于块执行期间的对象。形参是一种自动对象。

    局部静态对象:局部变量的生命周期贯穿函数调用及之后的时间。在程序第一次经过对象定义语句时初始化,并且直到程序终止时才被销毁,在此期间即使对象所在的函数结束执行也不会对它有影响。 只需要在定义变量之前加static即可。

6.如果形参是引用类型,他将绑定到队形的实参上,称它对应的实参被引用传递或函数被传引用调用。 

    如果形参不是引用类型,会将实参的值进行拷贝赋值给形参,称实参被值传递或者函数被传值引用。

7.通过使用引用形参,允许函数改变一个或多个实参的值。如果函数无需改变引用形参的值,可以将其声明为常量引用 const string &s1。 建议尽量使用常量引用。

8.拷贝大的类类型对象或者容器对象比较低效,甚至有的类类型不支持拷贝操作,这时候只能通过引用形参访问该类型的对象。

9.虽然说引用只能绑定到对象上,但有一种例外是当引用是常量引用是可以绑定到字面值和常量上,例如const int &a=42.

10.因为数组操作中不允许拷贝以及使用数组会转换为指针操作,所以无法以值传递的形式来使用数组参数,但是可以转换为指针来进行操作,传递的是首元素的指针。

     void print(const int* / int[ ]) {.....}         .........  int j[2]={0,1};    print(j);    

     形参也可以是数组的引用   void print (int (&a)[10]){...........}    a是具有10个整数的整型数组的引用.

11.处理不同数量的实参,如果所有的实参类型相同,可以使用标准库类型initializer_list,用于表示某种特定类型的值的数组。定义在<initializer_list>头文件中。

12.return语句有两种形式: return;   return expression;

      无返回值的return语句只能用于返回类型是void的函数中,通常void函数想要在中间提前退出,可以使用return语句。

      有返回值的return语句:只要函数的返回类型不是void,则必须有返回值。return语句返回值的类型必须与函数返回类型相同,或者能隐式的转换成函数的返回类型。

      值得注意的是:在含有return语句的循环后应该也有一条return语句。很容易忽视这个错误。

13.函数完成后,所占用的存储空间也随之被释放,因此函数终止意味着局部变量的引用将指向不再有效的内存区域。

14.如果同一作用域内的几个函数名相同但形参列表不同,称之为重载函数。main函数不能重载

15.对于重载函数来说,应该在形参数量或形参类型上有所不同;不允许两个函数除了返回类型以外其他所有的要素都相同。

16.函数匹配是指一个过程,在这个过程中把函数调用与一组重载函数中的某一个关联起来。当调用重载函数会有三种结果:最佳匹配、无匹配和二义性调用。

      如果在内层作用域中声明名字,它将隐藏外层作用域中声明的同名实体。在不同的作用域中无法重载函数名。

      一旦当前作用域中找到了所需的函数名,编译器就会忽略掉外层作用域中的同名实体。

     名字查找发生在类型检查之前。

17.默认实参:在函数每次调用时某个形参都被赋予了一个相同的值,这个值就是默认实参。调用含有默认实参的函数时,可以包含该实参,也可以省略。

      一旦某个形参被赋予了默认值,他后面的所有形参都必须有默认值。

18.调用函数一般比求等价表达式要慢一点,可以将函数指定为内联函数避免调用的开销。在函数返回类型之前加inline。

19.constepr函数指能用于常量表达式的函数,要求返回类型和所有形参的类型都得是字面值类型,而且函数体内有且只有一条return语句。constexpr被隐式的指定为内联函数。

20.预处理功能assert和NDEBUG。程序可能包含一些用于调试的代码,但在程序发布时需要屏蔽这些代码。此时可以用到与处理功能。

      assert是一种预处理宏,或者说是一个预处理变量。使用表达式作为条件  assert(expr);   首先对expr求值,若为假0则输出信息并终止程序,若为真(非0)则什么都不做。

      assert常用于检查“不能发生”的条件。

      assert依赖于NDEBUG的预处理变量的状态。如果定义了NDEBUG,则ASSERT什么都不做,默认状态下没有定义NDEBUG,此时ASSERT将执行运行并检查。

      NDEBUG除了用于assert以外,可以自己的条件调试代码,如果NDEBUG未定义,将执行#IFNDEF和#ENDIF之间的代码。如果定义了NDEBUG,这些代码将被忽略掉。

21.函数匹配第一步是选定本次调用对应的重载函数集,集合中的函数称为候选函数。候选函数有两个特征:预被调用函数同名;其声明在调用点可见。

      第二步考察本次调用提供的实参,然后从候选函数中选出能被这组实参调用的函数,这些新选出的函数称为可行函数。可行函数有两个特征:形参数量与本次调用的实参数量相等;每个实参与对应的形参类型相同或者可以转换。

     如果函数含有默认实参,则在调用该函数时传入的实参数量可能少于实际的实参数量。 

     第三步从可行函数中选择与本次调用最匹配的函数。基本思想是实参类型与形参类型最接近匹配的越好。

     如果(42,12.4) 可以调用f(int,int) ,也可以调用f(double,double),此时这个调用会因为具有二义性而拒绝,从而出现错误。

22.函数指针指向的是函数而非对象,函数指针指向某种特定类型,想要声明一个可以指向该函数的指针,只需要用指针替换函数名即可。int (*p)(.........){......}


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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值