c++基础3

1.权限放大和缩小

我们可以发现这里的权限放大是编译不通过的,其他都是可以的。

 

2.内联函数  inline

内联函数是一种编译器优化手段,它的主要作用是减少函数调用的开销,提高程序的执行效率。

一方面,函数调用通常会涉及栈帧的创建和销毁,以及参数的传递和返回值的处理等操作,这些操作都会导致额外的时间和空间开销。而内联函数会将函数体直接插入到调用位置,避免了这些操作,从而减少了执行时间。

另一方面,内联函数的插入是由编译器自动完成的,它可以对函数体进行更多的优化,比如常量折叠、循环展开等,从而进一步提高程序的执行效率。

总的来说,内联函数的意义和作用主要体现在两个方面:

1. 减少函数调用的开销,提高程序的执行效率;
2. 进一步优化函数体,提高程序的执行效率。

我们知道在调用函数时,就会相应的开辟栈帧,内联函数就是将函数展开在执行的地方,这样就可以减少调用的开销。但是需要注意的是内联函数只是一种建议,具体执不执行害得看编译器。

 

这里我们需要调用多次add函数,如果每次调用都创建栈帧就消耗过大,如果我们将其改为内联函数,那么就可以展开在调用的地方,就可以不用多开辟栈帧。

需要注意的是 在debug模式下,需要对编译器进行设置,否则不会展开(因为debug模式下,编译器默认不会对代码进行优化。

虽然内联函数具有提高程序执行效率的优点,但也存在一些缺点:

  1. 代码膨胀:内联函数会将函数体直接插入到调用位置,如果函数体过长或者被频繁调用,那么会导致代码膨胀,增加可执行文件的大小。

  2. 编译时间增加:内联函数需要在编译阶段进行函数体的插入,如果有大量的内联函数,会增加编译时间。

  3. 编译器决策:内联函数的最终决策是由编译器完成的,无法直接控制内联,有些编译器可能会选择不将函数内联,导致无法实现预期的优化效果。

  4. 可维护性降低:内联函数的定义和实现通常放在头文件中,如果内联函数发生了改变,会导致所有调用该函数的地方都需要重新编译。

总结:

1.inline是一种以空间换时间的做法,如果编译器将函数当成内联函数处理,在编译阶段,会用函数体替 换函数调用,缺陷:可能会使目标文件变大,优势:少了调用开销,提高程序运行效率。

 2. inline对于编译器而言只是一个建议,不同编译器关于inline实现机制可能不同,一般建议:将函数规 模较小(即函数不是很长,具体没有准确的说法,取决于编译器内部实现)、不是递归、频繁调用的函数 采用inline修饰,否则编译器会忽略inline特性。

3.使用内联函数需要谨慎,并根据具体情况进行合理的选择。只有在函数调用开销很大且频繁调用的情况下,才适合使用内联函数来提高程序的执行效率。

宏的优缺点:

 优点: 1.增强代码的复用性。

2.提高性能。

缺点: 1.不方便调试宏。(因为预编译阶段进行了替换)

2.导致代码可读性差,可维护性差,容易误用。

3.auto

auto是C++11引入的一个关键字,用于自动推导变量的类型。使用auto关键字声明变量时,编译器会根据初始化表达式的类型推导出变量的类型。

auto的主要优点是简化代码,减少冗余的类型声明。使用auto可以让编译器根据初始化表达式的类型自动推导出变量的类型,避免手动指定类型的繁琐过程。

auto x = 5;   // 推导为int类型
auto y = 3.14;   // 推导为double类型
auto z = "hello";   // 推导为const char*类型

需要注意的是,auto并不是完全代替了显式类型声明,在某些情况下仍然需要显式指定变量类型,例如函数参数、函数返回值、泛型编程等。此外,由于auto是在编译时进行类型推导,因此在运行时无法改变推导出的变量类型。

总之,auto关键字提供了一种简化代码的方式,通过自动推导变量类型减少冗余的类型声明,使代码更加简洁和易读。需要注意的是auto不能作为函数参数,也不能用来定义数组。

不能作为函数参数:函数参数需要在函数声明时确定其类型,以便在函数调用时进行类型匹配。而auto用于自动推导变量类型,是在初始化时通过变量的初始值来确定类型的。由于函数参数在函数声明时并没有初始值可供推导,因此无法使用auto来声明函数参数。

不能用来定义数组:数组的大小和元素类型需要在编译时确定,而auto关键字是用于在编译时根据初始化表达式自动推导变量的类型。

typedef char* pstring;
int main()
{
 const pstring p1; // 编译成功还是失败?
 const pstring* p2; // 编译成功还是失败?
 return 0;
}
  1. const pstring p1; 编译失败,因为const修饰的指针p1必须被初始化,而此处未进行初始化。

  2. const pstring* p2; 编译成功,因为p2是一个指向const pstring类型的指针,没有要求必须初始化。

auto与指针和引用结合起来使用:

用auto声明指针类型时,用auto和auto*没有任何区别,但用auto声明引用类型时则必须加&

int main()
{
 int x = 10;
 auto a = &x;
 auto* b = &x;
 auto& c = x;
 cout << typeid(a).name() << endl;
 cout << typeid(b).name() << endl;
 cout << typeid(c).name() << endl;
 *a = 20;
 *b = 30;
 c = 40;
 return 0;
}

这里的typeid().name()还帮助我们了解参数类型的函数,头文件是#include<typeinfo>.

谢谢
  • 33
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

c23856

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值