C++ Prime Plus 第8章 函数探幽 知识点总结

1 内联函数inline

  1. 目的:为提高程序的运行速度
  2. 与常规函数的区别:
    1)被调用时的运行机制不一样
    2)编译器使用函数代码替换来代替函数调用
  3. 如何选择内联函数和常规函数:当代码执行时间很短时,远小于函数调用机制所花费的时间时,就使用内联函数。否则,没有必要使用内联函数。
  4. 内联函数的使用:
    1)一般将整个函数定义放于函数原型处,并加上inline关键词。如:
    inline void add (int a, int b) { return a + b; }
    2)即使你使用了inline,编译器也不一定会使用。当你定义的inline函数中代码过长,或者有递归时等情况,都不会使用定义的inline。
  5. C++中的inline就相当于C中的define宏。

2 引用变量&

  1. 目的:主要用途是用于函数的形参,通过将引用作为函数的参数,可以直接使用原始数据,而不是副本。对于类和结构等占据内存较大的变量,建议使用引用,这样可以节省时间和内存。
  2. 定义:引用是已定义的变量的别名,相当于一个变量,多个名称。引用的变量不能为表达式。
  3. 引用的创建与初始化:
    1. 引用必须在声明时进行初始化,不能先声明,再初始化。正确示例:int & rodents = rats;当然rats变量是之前就已经定义的。
    2. 不可以直接引用常量。错误示例:double & d = 12.3; d = 110; 这点我不太明白
    3. 可以指向常量的引用。正确示例:const double & d = 12.3;
    4. 可以通过初始化来设置引用,但不能通过赋值来设置。这点也不是很明白
  4. 引用作为函数参数按引用传递,允许被调用的函数能够访问调用函数中的变量。
    1) 原因:
    能够修改调用函数中的数据对象
    可以提高程序的运行速度
    2) 原则:
    按值传递: 如果数据对象很小,如内置数据类型或小型结构
    按指针传递:如果数据对象是数组,唯一选择
    按引用传递:如果数据对象是较大的结构或类对象,以提高程序的效率,节省复制的时间和空间。
    3)比较按引用传递和按值传递:
void Swapr (int &a, int &b);
void Swapv (int a, int b);
  • 声明函数参数的方式不同
  • 变量a和b一个是别名(原始数据),一个是副本
    4) 比较按引用传递和按指针传递
void Swapr (int &a, int &b);
void Swapp (int *a, int *b);
  1. 声明函数参数的方式不同
  2. 按指针传递时,整个过程要使用解除引用运算符*
  3. 临时变量
    1) 何时生成临时变量:
    实参类型正确,但为字面常量或表达式。
    实参类型不正确,但可以转换为正确的类型。
    2) 生存周期: 只在函数调用期间,此后会被编译器删除
    3) 函数参数应尽可能使用const引用:
    使用const可以避免无意中修改数据
    使用const是函数可以接受const和非const实参,否则只能接受非const数据
    使用const引用使函数能够正确生成和使用临时变量
  4. 返回引用:效率更高
    1)不要返回局部变量的引用
    2) 返回引用时,要求函数参数中包含被返回的引用对象
    3) 函数可以不返回值,默认返回传入的引用对象本身
    4) 使用const用于返回引用时,是为了让函数返回的是不可修改的左值,不能被赋值。
  5. 继承在引用上的特性:基类引用可以指向派生类的对象,无需进行强制转换,即可以定义一个接受基类引用作为参数的函数,调用该函数时,既可以将基类对象作为参数,也可以将派生类对象作为参数。

3 默认参数

  1. 必须通过原型设置默认值
  2. 要为某个参数设置默认值,则必须为他右边的所有参数提供默认值
  3. 通过使用默认参数,可以减少要定义的析构函数/方法以及方法重载的数量

4 函数重载

  1. 目的:完成相同的工作,但使用不同的参数列表,即函数名相同,函数特征标不同(参数数目/参数类型不同),但与函数返回类型无关
  2. 编译器在检查函数特征标时,将按引用传递和按值传递视为同一个特征标。
  3. 重载引用参数
void sink(double &r1);
void sink(const double &r2);
void sink(double &&r3);

1) 左值引用参数r1与可修改的左值参数匹配
2) const左值引用参数r2与==可修改的左值参数、const左值参数和右值参数(如两个double值的和)==匹配
3) 左值引用参数r3与左值匹配

5 函数模板

  1. 目的:函数处理过程一样,传入参数不一样时,采用函数模板来作为通用的函数描述。它可以使生成多个函数定义更简单和可靠。
  2. 建立函数模板:
    1. 模板头与函数原型和函数定义是不可分割的一个整体:
      模板函数原型:
template <typename T>
void Swap (T &a, T &b);

模板函数定义:

template <typename T>
void Swap (T &a, T &b)
{
...
}

其中,T可以接受int/double/…参数,编译器会生成对应版本的函数。

  1. 模板函数重载:只要特征标不一样即可。例如:
    输入参数为引用:
template <typename T>
void Swap (T &a, T &b);

输入参数为指针,且包含一个具体类型:

template <typename T>
void Swap (T *a, T *b, int n);
  1. 显式具体化:例如当你要把一个结构赋给一个结构时,只想将某些成员进行赋给,并不是所有时,无法使用模板重载来实现,即用结构来代替T。
    1) 原型和定义要以template <>开头,并通过名称指出类型:其中job就是类型
template <> void Swap <job> (job &, job &);//第一种写法
template <> void Swap (job &, job &);//第二种写法

2) 编译器选择原型时,非模板函数>显示具体化>模板函数

  1. 实例化和具体化
    1) 隐式实例化:编译器使用模板为特性类型生成函数定义时,得到的就是模板实例。例如:
Swap(i,j);//其中i,j为int型

2) 显示实例化:直接命令编译器创建特定的实例。声明语法为:template void Swap<int> (int, int);
调用时:Swap(i,j);
3) 隐式实例化、显示实例化和显示具体化统称为具体化。它们表示的都是使用具体类型的函数定义,而不是通用描述。

  1. decltype关键字
template<class T1, class T2>
void ft (T1 x, T2 y)
{
...
??? xpy = x + y;
...
}

这个时候xpy为什么类型呢?使用关键字decltype就可以解决,decltype (expression) var 按顺序依次:
1) 如果expression是一个没有用括号括起来的标识符,则var的类型与该标识符类型一样,例如:

const double * p;
decltype(p) v;//v与p的类型一样,均为 const double *

2) 如果expression是一个函数调用,则var的类型函数的返回类型一样,例如:

long indeed(int);
decltype (indeed(3)) m;//m的类型为long

3) 如果expression是一个左值,也就是用括号括起来的标识符,则var的类型为指向其类型的引用,例如:

double xx = 4.4;
decltype((xx)) r2 = xx;//r2的类型为double &

4) 如果前面的条件均不满足,则var的类型与expression的类型一样,例如:

int j = 3;
decltype(j+3) i;//i的类型为(j+3)的类型,也就是int
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
回答: 在C语言中,string函数是一个字符串处理函数库,它包含在<string.h>头文件中。其中常用的函数有strcpy、strlen和strnset。 strcpy函数用于将一个字符串复制到另一个字符串中。它的函数原型是:char *strcpy(char *dest, const char *src)。其中,dest是目标字符串,src是源字符串。这个函数会将src字符串的内容复制到dest字符串中,并返回dest字符串的指针。\[1\] strlen函数用于计算字符串的长度。它的函数原型是:size_t strlen(const char *str)。这个函数接收一个字符串的首地址,然后遍历字符串直到遇到'\0'字符,返回字符串的长度。\[2\] strnset函数用于将指定的字符替换字符串中的一部分字符。它的函数原型是:char *strnset(char *str, int c, size_t n)。其中,str是要操作的字符串,c是要替换的字符,n是要替换的字符个数。这个函数会将字符串中的指定部分字符替换为指定的字符。\[3\] 这些函数都是C语言中常用的字符串处理函数,可以帮助我们进行字符串的复制、长度计算和字符替换等操作。 #### 引用[.reference_title] - *1* *3* [C语言中string函数详解](https://blog.csdn.net/weixin_30902251/article/details/99781150)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [c语言String字符串函数探幽](https://blog.csdn.net/Duary/article/details/106163396)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值