C++篇:第四章_函数_知识点大全
五、函数
(一)函数使用规则
函数的定义不能嵌套但调用可以嵌套
在函数调用时,如某一默认参数要指明一个特定值,则有其之前所有参数都必须赋值
赋默认实参时 一旦某个形参被赋予了默认值,它后面的所有形参都必须有默认值,因为设置默认参数的顺序是自右向左;且注意默认值不可以是局部变量
函数参数的默认值可以是表达式
如果在函数定义时设置了默认参数,则就不能在函数声明时再次设置,反之亦然
函数只有一个 返回值,除void类型函数
函数调用可以出现在执行语句中,也可以出现在表达式中,甚至还可以作为一个函数的实参,但不可作为函数的形参,因为函数返回值存在寄存器中, 没有地址, 不能作为形参
函数是一种特殊的数据类型,正确
当函数不是void类型且函数体内没有return语句时,此时函数的返回值与返回类型相同但内容却是随机的一个值
C++所有的函数本质上都是外部函数(可延申至其他文件中使用),故extern关键字可省略
如果函数的形参是指向普通变量的指针变量,实参只能用指向普通变量的指针,不能用指向const变量的指针,反之则都可以用
当函数自变量个数不确定时,系统不自动检测自变量
13. 函数三种传参:
① 值传递:会为形参重新分配内存空间 ,将实参的值拷贝给形参,形参的改变不会影响实参的值,函数被调用结束后,形参被释放。
② 地址的传递:形参为指针变量,将实参的地址传递给函数,可以在函数中改变实参的值。调用时为形参指针变量分配内存,结束时释放指针变量。
③ 引用传递:不会为形参重新分配内存空间,形参只是实参的别名,形参的改变只会影响实参的值,函数调用结束后,形参不会被释放。
(二)函数的使用
建立自定义函数,调用时只需要明白函数的功能即可,故提高了程序的可读性
sizeof 返回的值表示的含义如下(单位字节):
数组 —— 编译时分配的数组空间大小;
指针 —— 存储该指针所用的空间大小(存储该指针的地址的长度,是长整型,应该为 4 );
类型 —— 该类型所占的空间大小;
对象 —— 对象的实际占用空间大小;
函数 —— 函数的返回类型所占的空间大小。函数的返回类型不能是 void
sizeof(float)是(整型)类型表达式
Math.floor() 表示向下取整,返回double类型
Math.ceil() 表示向上取整,返回double类型
Math.round() 四舍五入,返回int类型
用户可以重载(不能重定义)标准库函数,若如此,该函数将失去原有含义;但若已包含标准库头文件及相关命名空间,则系统不允许用户重新定义标准库函数,因为两个相同作用域内的函数 如果除了返回值类型外 的函数要素都相同 那么编译器会报重定义错误
函数返回值作为右值,被const修饰无效,故此时const相当于没修饰
如果参数类型不一致,则函数调用时按形参类型隐式类型转换实参
main函数默认返回一个int类型的值
将一个字符串传递到函数中,传递的是地址,则函数形参既可以用字符数组,又可以用指针变量
函数的返回值可以是引用类型且函数返回引用可以作为左值
函数的返回类型可以是结构体类型,这时函数将返回一个结构体对象
所有的函数在定义它的程序中都是可见的
(三)预处理命令(包括宏定义)
预处理命令行不能以分号结尾
预处理命令行可以出现在程序的最后一行
预处理命令行作用域是从出现位置开始到源程序文件末尾
凡是以#号开头的行,不一定都为编译预处理命令行
在源文件的一行上不可以有多条预处理命令
预处理不做语法检查
C++在编译前由预处理器对预处理命令进行处理(故在编译前被执行),编译时进行语法分析
宏替换不占用程序的运行时间,只占编译时间
(四)内联函数与宏的区别
- 内联函数在运行时可调试,而宏定义不可以;
- 编译器会对内联函数的参数类型做安全检查或自动类型转换(同普通函数),而宏定义则不会;
- 内联函数可以访问类的成员变量,宏定义则不能;
- 在类中声明同时定义的成员函数,自动转化为内联函数。
(五)函数与宏的区别
宏做的是简单的字符串替换(注意是字符串的替换,不是其他类型参数的替换),而函数的参数的传递,参数是有数据类型的,可以是各种各样的类型.
宏的参数替换是不经计算而直接处理的,而函数调用是将实参的值传递给形参,既然说是值,自然是计算得来的.
宏在编译之前进行,即先用宏体替换宏名,然后再编译的,而函数显然是编译之后,在执行时,才调用的.因此,宏占用的是编译的时间,而函数占用的是执行时的时间.
宏的参数是不占内存空间的,因为只是做字符串的替换,而函数调用时的参数传递则是具体变量之间的信息传递,形参作为函数的局部变量,显然是占用内存的.
函数的调用是需要付出一定的时空开销的,因为系统在调用函数时,要保留现场,然后转入被调用函数去执行,调用完,再返回主调函数,此时再恢复现场,这些操作,显然在宏中是没有的.
宏替换不占用程序的运行时间
宏与类型无关,但是c++中函数必须指定返回类型,故宏可以做函数不能做的事
(六)函数模板
1.函数模板的格式如下:
Template <class 形参名,class 形参名,......> 返回类型函数名(参数列表){函数体}
其中,class可以用typename关键字代替
- 函数模板调用时不需要显式指定类型,系统自动匹配参数类型,若没有合适的,会进行报错。而类模板使用需要显式指定类型,且对于函数模板注意要返回值和参数的类型一致
- 模板函数和普通函数都符合条件时,优先执行普通函数
- 模板特化:(当函数模板需要对某些类型进行特化处理,称为函数模板的特化,类模板的特化同理)
① 因为很多时候,我们既需要一个模板能应对各种情形,又需要它对于某个特定的类型有着特别的处理,故出现了模板特化
① 特化整体上分为全特化和偏特化
② 全特化:就是模板中模板参数全被指定为确定的类型。 全特化也就是定义了一个全新的类型,全特化的类中的函数可以与模板类不一样
③ 偏特化:模板中的模板参数没有被全部确定,需要编译器在编译时进行确定
④ 对主版本模板类、全特化类、偏特化类的调用优先级从高到低进行排序是:全特化类>偏特化类>主版本模板类
⑤ 当函数调用发现有特化后的匹配函数时,会优先调用特化的函数,而不再通过函数模版来进行实例化
⑥ 模板特化相当于在声明了类模板等后声明需要模板特化然后让接下来的代码自己使用一个类型,故不能单独使用,例;![img](file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps386C.tmp.jpg)
5. 模板特化实现:template<> + 完全和模板类型没有一点关系的类实现或者函数定义;
① 特化为绝对类型(全特化):例:template<>class Compare{...}; // 特化为float类型,此为函数模板特化;函数模板只能全特化,没有偏特化
② 特化为引用,指针类型(半特化、偏特化):例:template struct iterator_traits<_Tp*> {};
③ 特化为另外一个类模板(偏特化):例:template class Compare<vector>{};
- 类模板的成员函数都是函数模板;没使用过的成员函数(即函数模板)不会被实例化
- 函数模板必须由程序员实例化为可执行的函数
- 函数模板的虚拟类型名是在编译阶段确定实际类型的
(七)函数重载
使用重载函数编程序的目的是:使用相同的函数名调用功能相似的函数;使用方便,提高可读性
重载函数的形参(个数或类型)必须不同
void x(int,char ch=’a’)与void x(int)可以在同一程序中定义,但不可以重载
(八)内联函数
1. 内联(置)函数inline:
引入内联函数的目的是为了解决程序中函数调用的效率问题;程序在编译器编译的时候,编译器将程序中出现的内联函数的调用表达式用内联函数的函数体进行替换,而对于其他的函数,都是在运行时候才被替代。这其实就是个空间代价换时间的节省(弊:代码被多次复制,增加了代码量,占用更多的内存空间),故在当函数代码较小并且被频繁调用的时候。在使用内联函数时要留神:
① 使用基类指针或引用来调用虚函数时,它都不能为内联函数(因为调用发生在运行时)。但是,使用类的对象(不是指针或引用)来调用时,可以当做是内联,因为编译器在编译时确切知道对象是哪个类的
② 默认情况下,在类体中定义的成员函数若不包括循环等控制结构,符合内联函数要求时,C++会自动将它们作为内联函数处理(不是所有成员函数都是内联函数)
③ 内联函数在编译时是将该函数的目标代码插入每个调用该函数的地方,不是运行时
④ 内联函数在编译时做参数类型检查
⑤ 在内联函数中不允许使用循环语句(for,while)和switch结果,带有异常接口声明的函数也不能声明为内联函数。另外,递归函数(自己调用自己的函数)是不能被用来做内联函数的。内联函数只适合于只有1~5行的小函数
⑥ 内联函数的定义必须出现在内联函数第一次调用之前
⑦ 定义内联函数inline写类型前面
⑧ 关键字inline 必须与函数定义体放在一起才能使函数成为内联,仅将inline 放在函数声明前面不起任何作用
⑨ 如果在类外定义inline函数,则必须将类定义和成员函数定义放在同一头文件中,否则编译时无法进行置换
⑩ 头文件中不仅要包含 inline 函数的声明,而且必须包含定义,且在定义时必须加上 inline
⑪ 不管是 class 声明中定义的 inline 函数,还是 class 实现中定义的 inline 函数,不存在优先不优先的问题
⑫ 内置函数不需要使用堆栈进行现场的保护与恢复
⑬ 用 inline 修饰的函数原型其对应的函数也将成为内联函数 - 错(自己理解:inline为建议型关键字)
⑭ 内联函数可以是静态的
C++篇:第四章_函数_知识点大全的更多相关文章
- Java语言程序设计(基础篇) 第四章 数学函数、字符和字符串
第四章 数学函数.字符和字符串 4.2 常用数学函数 方法分三类:三角函数方法(trigonometric method).指数函数方法(exponent method)和服务方法(service m ...
- Oracle学习总结_day03_day04_条件查询_排序_函数_子查询
本文为博主辛苦总结,希望自己以后返回来看的时候理解更深刻,也希望可以起到帮助初学者的作用. 转载请注明 出自 : luogg的博客园 谢谢配合! day03_条件查询_排序_函数 清空回收站: PUR ...
- Python基本语法_函数_参数的多类型传值
前言 上一篇主要介绍了Python函数的参数类型,本篇继续学习Python函数多类型传值. 目录 前言 目录 软件环境 参数的多类型传值 向函数传递Tuple 向函数传递List 向函数传递Dicti ...
- C Primer Plus_第9章_函数_编程练习
1.题略 /*返回较小值,设计驱动程序测试该函数*/ #include <stdio.h> double min (double a, double b); int main (void) ...
- 《Thinking in Java》十四章类型信息_习题解
1~10 Page 318 练习1. 在ToyTest.java中,将Toy的默认构造器注释掉,并解释发生的现象. 书中代码如下(略有改动): package org.cc.foo_008; p ...
- 1. js数据类型_对象_函数_内存
1. js数据类型有哪些? 基本(值)类型 Number ---- 任意数值 String ---- 任意字符串 Boolean ---- true/false undefined ---- unde ...
- python第四章:函数--小白博客
Python函数 函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段. 函数能提高应用的模块性,和代码的重复利用率.你已经知道Python提供了许多内建函数,比如print().但你也可 ...
- sql的一些知识_函数_汇总数据
汇总数据 avg()---------求平均数 值得注意的是:avg()只能用于一个列的平均值查询,多个列的平均值请使用多个avg() avg()忽略null值 count()-------计数(指定 ...
- Python基本语法_函数_返回值
目录 目录 前言 函数的返回值 在函数中Return和Print的区别 函数中的文档 前言 函数的返回值是函数重要的组成部分.函数的根本在于实现程序的部分功能,所以很多时候我们需要将函数执行后的结果返 ...
随机推荐
- 《前端运维》一、Linux基础--09常用软件安装
一.软件包管理 RPM是RedHat Package Manager(RedHat软件包管理工具)类似Windows里面的"添加/删除程序".软件包有几种类型,我们一起来看下: 源 ...
- OOS 预览报错解决思路
预览报错解决思路: 官方链接:https://docs.microsoft.com/zh-cn/officeonlineserver/office-online-server :> 查看服务器内 ...
- Discuz!X系列全版本后台sql注入复现
圈子某位大佬公布的0day,拿来刷一刷,漏洞分析请移步大佬文章.大佬链接 0x01 环境准备 1.首先去码云下载最新版本的discuz(DiscuzX 3.4 R20191201). 2.将upaod ...
- iOS全埋点解决方案-应用退出和启动
前言 通过应用程序退出事件,可以分析应用程序的平均使用时长:通过应用程序的启动事件,可以分析日活和新增.我们可以通过全埋点方式 SDK 实现应用程序的退出和启动事件. 一.全埋点的简介 目前. ...
- pytorch方面
(113条消息) Pytorch基础:Torch.mul.Torch.mm与Torch.matmul的异同_名字填充中的博客-CSDN博客_pytorch torch.mul (111条消息) pyt ...
- 高度不定,宽100%,内一div高不确定,如何实现垂直居中?
verticle-align: middle; 绝对定位50%加translateY(-50%) 绝对定位,上下左右全0,margin:auto
- memcached 能接受的 key 的最大长度是多少?
key 的最大长度是 250 个字符.需要注意的是,250 是 memcached 服务器端内 部的限制,如果您使用的客户端支持"key 的前缀"或类似特性,那么 key(前缀 + ...
- 如何实现集群中的 session 共享存储?
Session 是运行在一台服务器上的,所有的访问都会到达我们的唯一服务器上,这 样我们可以根据客户端传来的 sessionID,来获取 session,或在对应 Session 不 存在的情况下(s ...
- python学习笔记(一)——Python基础
一.python 基础语法 python 的解释器在启动时会自动加载一个内建的模块,因此我们在使用 print().input()等函数时不用导入其他模块文件. 基本语法: 每条语句结尾没有分号 定义 ...
- Tensorflow安装教程(Anaconda)
写在最前: 在安装过程中遇到很多坑,一开始自己从官网下载了Python3.6.3或者Python3.6.5或者Python3.7.1等多个版本,然后直接pip install tensorflow或者 ...