C++基本语言:1.6函数新特性、内联函数、const

C++基本语言包含10章节内容,存于C++从入门到精通专栏

目录

一、函数回顾与后置返回类型

二、内联函数

三、函数杂合用法总结

四、const char *、char const * 与  char *const 三者的区别

五、函数形参中带const

一、函数回顾与后置返回类型

函数声明(函数原型)的一般形式:类型标识符 函数名(形参);//提前指明

函数定义:类型标识符 函数名(形参){函数体}

函数声明时,是可以没有形参名的。虽然写形参名会帮助自己和其他读代码的人更好地理解代码,但是编译器会忽略形参名

01141f3484654ebe9aeb9c67e2fcf938.png

函数定义中,形参如果并不在这个函数中使用,则不给形参名也可以,但在调用这个函数的时候,该位置的实参是必须要明确给出的

C++基本语言:1.6函数新特性、内联函数、const_第1张图片

①“前置返回类型”:把函数的返回类型放到函数名之前

② C++中引入了“后置返回类型”,就是在函数声明或者定义中,把返回类型写在参数列表之后

C++基本语言:1.6函数新特性、内联函数、const_第2张图片

说明:

auto :类型自动类型推断

前面放置auto关键字,表示函数返回类型放到参数列表之后

而放在参数列表之后的返回类型是通过 “->”开始的

二、内联函数

在函数定义之前增加了一个inline关键字,增加了这个关键字的函数,叫作内联函数。

60f3f6c852724fa88d52d5ba14032905.png

调用函数是要消耗系统资源的,尤其是一些函数体很小但却频繁调用的函数,调用起来很不划算,因为要频繁地进行压栈、出 栈动作以处理函数调用和返回的问题,这也意味着要频繁地为它们开辟内存。

为了解决这种函数体很小、调用又很频繁的函数所耗费的系统性能问题,引入了inline关键字。该关键字的效果如下:

(1)影响编译器,在编译阶段完成对inline函数的处理,系统尝试  将调用该函数的动作 替换为 函数的本体(不再进行函数调用)。通过这种方式,来提升程序执行性能。

(2)inline关键字只是程序员(开发者)对编译器的一个建议,编译器可以尝试去做,也可以不去做,这取决于编译器的诊断功能,也就是 说决定权在编译器,无法人为去控制。

(3)一般将函数声明放在一个头文件中;函数定义放在一个.cpp源文件中。但是内联函数恰恰相反, 内联函数的定义就放在头文件中

如果要把函数定义放在头文件中,那么超过1 个.cpp源文件要包含这个头文件,系统会报错。也就是说两个cpp文件包含头文件(特指有函数定义的头文件),系统会报错————函数重复定义了

内联函数的定义就放在头文件中。why?

这样需要用到这个内联函数的.cpp源文件,都能通过#include来包含这个内联函数的源代码

(目的是找到函数本体,并尝试将函数的调用替换成函数体内的语句)

inline优缺点:

代码膨胀问题,所以内联(减少压栈)函数函数体尽量要小,以节省内存

注意:各种编译器对inline的处理各不相同,inline函数尽可能简单,代码尽量少

尤其是 循环、分支、递归调用尽量不要出现在inline函数中。否则,编译器可能因为你写这些代码的原因,拒绝让这个函数成为一个inline函数

比如,constexr int mf(){};这种函数也可以看成是一种更为严格的一种内联函数,也需要写的很简单

#define//宏展开,也类似于inline

当然 define VS inline也有区别

三、函数杂合用法总结

(1)函数返回类型为void表示函数不返回任何类型。但是,可以调用一个返回类型为void的函数让它作为另一个返回类型为void的函数的返回值。

C++基本语言:1.6函数新特性、内联函数、const_第3张图片

(2)函数返回指针和返回引用的情况

C++基本语言:1.6函数新特性、内联函数、const_第4张图片

临时变量的地址会被系统回收,你现在指向了一个你不应该操作的内存地址;你往一个不属于你的地址写了你的数字

再比如

C++基本语言:1.6函数新特性、内联函数、const_第5张图片

如果你用一个整型变量来接,那么他两的地址是不一样的;这个地址就是安全的

C++基本语言:1.6函数新特性、内联函数、const_第6张图片

(3)不带形参的函数定义也可以写成如下,或者形参列表直接空着更好。

ddcf9692fc944415aede4c0bd802c4c4.png

(4)如果一个函数不调用,则该函数可以只有声明部分,没有定义部分

(5)普通函数,函数声明一般放在头文件中,函数定义一般放在源文件中,所以函数只能定义一次,但可以声明多次,因为多个源文件可能都包含一个头文件,而且习惯上,函数定义的源文件中也把函数声明的头文件包含进来。

引用类型作为函数的形参void func(int&ta,int&tb),在函数中改变值会直接影响到外界实参的值(所以通过这种手段相当于间接实现函数能够返回多个值的能力)。

否则实参和形参之间就是值传递,那就存在实参值复制给形参(值复制的问题)。

如果传递的参数是很大的类对象(结构变量),这种值复制的效率是很低的,此时,就要考虑通过“引用型形参来进行函数调用参数的传递”

C++中,更习惯用 引用类型的形参 来取代指针类型的形参,在C++中多使用引用类型的形参

C++基本语言:1.6函数新特性、内联函数、const_第7张图片

(7)C语言中,函数允许同名,但是形参列表的参数类型或者数量 应该有明显区别,这叫函数重载。

C++基本语言:1.6函数新特性、内联函数、const_第8张图片

上面这对重载的函数不可以,因为const关键字在比较同名函数时会 被忽略掉。这两个函数相当于参数类型和数量完全相同,因此函数重载不成立,编译链接时会报错。

下面两个就可以:

C++基本语言:1.6函数新特性、内联函数、const_第9张图片

这对重载的函数可以,没有问题,因为形参的类型并不相同,一 个是int类型,一个是float类型。

C++基本语言:1.6函数新特性、内联函数、const_第10张图片

这对重载的函数可以,没有问题,因为形参的数量不相同

四、const char *、char const * 与  char *const 三者的区别

const int abc=12;

char *p与const混用

(1)const char *p; P所指向的目标,那个目标中的内容不能通过P来修改

        P指向的地址可以变;但可以通过str[0]进行修改

C++基本语言:1.6函数新特性、内联函数、const_第11张图片

(2)const char *p ===char const *p const放在中间或者最前面都可以

(3)char * const p; 定义时候必须初始化,P一旦指向了一个东西之后,就不可以指向其他东西

C++基本语言:1.6函数新特性、内联函数、const_第12张图片

(4)“const char*constp=str; ”或“char const * const p; ” 结合了 

        (1)~(3),表示p的指向不能改变,p指向的内容不能通过 p来改变。        

举例说明:

f21a22b0fe5243d29f449e73cc058f06.png

C++基本语言:1.6函数新特性、内联函数、const_第13张图片

//系统给b分配了一段内存,引用实际是分配内存的

五、函数形参中带const

C++基本语言:1.6函数新特性、内联函数、const_第14张图片

注意:如果不希望在函数fs中修改形参stu里的值,建议形参最好使用常量引用

C++基本语言:1.6函数新特性、内联函数、const_第15张图片

再看如下式子:

ff26f717f76d40fea619cd3033da8be4.png

这种把形参写成const形式的习惯有许多好处:

 (1)可以防止无意中修改了形参值导致实参值被无意中修改掉。

 (2)实参类型可以更加灵活。

C++基本语言:1.6函数新特性、内联函数、const_第16张图片

C++基本语言:1.6函数新特性、内联函数、const_第17张图片

再比如

C++基本语言:1.6函数新特性、内联函数、const_第18张图片

你可能感兴趣的:(C++从入门到精通,c++,开发语言)