C++入门编程 ---- 助你更好理解C++的奥妙(三)

简介: C++入门编程 ---- 助你更好理解C++的奥妙(三)

内联函数:

内联函数 就是函数名前面以inline修饰的函数 编译时c++编译器会在调用内联函数的地方展开(篇幅小的函数才会展开 编译器会自动识别) 没有函数调用建立栈帧的开销。内联函数可以提升程序运行的效率  所以我们经常调用的小函数就适合


 这个替换的机制是不是和C语言里面的  宏  很相似呢 但是他们两个是不相同的 就好像 我们的宏是不能够调试的 但是我们的内联函数可以调试的

大家觉得为什么c++要有一个这个内联函数呢? 首先我们的宏是替换 如果我们写得时候没有注意 优先级 那么是有可能出错的 大家学习宏的时候应该有所体会吧 但是我们自己写函数时容易出错嘛? 还有就是我们的内联函数的特性 是去把一个函数展开 不用开辟栈帧


默认的debug版本下不会展开 只有优化后的 或者 自己去调了设置的才会看到像下面这样的没有 call 的 

3524d745840a4d788e01574606758ee6.png

 大家看这里面就没有call指令了 不会去调用函数了


内联函数的特性:

  inline是一种 空间换取时间 的做法,这样为我们省去了开辟栈帧的开销  当然也不是说我们内联函数哪里都可以适用,像对于我们的很长的代码或者你这个函数里面包含有递归的这些内联函数就不太适用了

  其次,我们的inline对于编译器只是一个建议,编译器会自己判断、优化,像如果是上面那种不适用的情况,我们编译器就会忽略掉它的内联 大家来看:

4a8fcdba7aba408b9ded6e15d26b21ad.png 篇幅小的会替换 大家来看篇幅大的:

c349cf431cd740288f9c87fd6be92801.png大家看到篇幅大的它还会替换嘛 它是不是就是去调用call指令了 


另外大家在使用inline的时候还一个要注意的点就是,我们的函数因为inline展开后,是没有函数地址的,所以大家在使用的时候,不要把 声明 定义 分离 因为这样的话后面程序在链接的时候就会出现链接不上的问题


我们的程序在执行的时候分为这么四个步骤   预处理->编译->汇编->链接  我们的汇编会利用编译期间实现过的符号汇总来进行一个 形成符号表的操作 如果有的符号没有地址的话 就是属于声明 和 定义分离了 只有声明是没有地址的  所以就会在链接的时候进行一个 符号表的合并和重定位(多个目标文件(.o)进行链接的时候会通过符号表查看来自外部的符号是否存在)

f5c8446d669e48b193acd91803e106f5.png


auto:

auto是一个新的类型指示符来指示编译器,auto声明的变量必须由该编译器在编译时期推导而得 意思就是它可以自动的去推导一个变量是什么类型

int a=10;
auto b=a;
auto c='d';


 对于这个我们后面学习迭代器的时候用起来还是很方便的 就像那些类型名很长的这个就挺适用的


还有这样的场景:auto& auto* 这两个得意思是 我们表明了我们传过去得变量得是一个引用或者是指针

int a = 10;
auto& = a;
auto* = &a;
auto* = a;


最下面得那种写法就是错误得 因为我们指定了传过去的得是一个指针


如果说在同一行声明多个变量时,这些必须得是相同得类型,因为这时我们得auto是先自动推导第一个变量的类型再拿推导出来的类型去定义以后的变量

auto a=1,b=2.0;


这样就是不对的

auto 还有一个应用场景: 就是我们的范围for

我们以前的for循环:for(int i=0;i<size;i++)  就好像是这样 我们的范围for是可以这样写的: 

for(auto ch:arr)
{
    //依次自动取arr中的数据,赋值给ch,会自动判断结束
}


虽说我们是依次把arr中的值赋值给ch 但ch始终是一个拷贝 我们是不能通过ch直接改变arr数组中的内容的

for(auto& ch:arr)
{
    //取别名后 就可以直接改变arr数组里面的值了
}


有一个点大家要注意我们使用的数组的范围必须是固定的,不能是不确定的 大家看下面的代码我们传进来的参数是一个数组首元素的地址 哪怕是常规的for循环也是不能直接使用arr的

void test(int arr[])
{
    for(auto ch:arr)
    {
        ;
    }
}


auto不适用的场景:

① auto不能作为函数的参数  因为在编译阶段会报错 编译器那时无法推导具体类型

auto也是不能做返回值的哦

② auto也不能用来声明一个数组


nullptr:

再c++11中 我们的NULL 和 0 是等价的 大家可以到stddef.h文件去看一下 而我们的nullptr就是为了弥补这个缺陷,好像我们平常同时使用 NULL 和 0 时系统就会使用最前面的那个了那我写在后面的 0 或 NULL 不就没有用了嘛,所以有了nullptr

所以我们在c++中表示一个空指针都是用的 nullptr 

目录
相关文章
|
29天前
|
C++
C++ 语言异常处理实战:在编程潮流中坚守稳定,开启代码可靠之旅
【8月更文挑战第22天】C++的异常处理机制是确保程序稳定的关键特性。它允许程序在遇到错误时优雅地响应而非直接崩溃。通过`throw`抛出异常,并用`catch`捕获处理,可使程序控制流跳转至错误处理代码。例如,在进行除法运算或文件读取时,若发生除数为零或文件无法打开等错误,则可通过抛出异常并在调用处捕获来妥善处理这些情况。恰当使用异常处理能显著提升程序的健壮性和维护性。
42 2
|
1月前
|
安全 编译器 程序员
【C++初阶】C++简单入门
【C++初阶】C++简单入门
|
29天前
|
算法 C语言 C++
C++语言学习指南:从新手到高手,一文带你领略系统编程的巅峰技艺!
【8月更文挑战第22天】C++由Bjarne Stroustrup于1985年创立,凭借卓越性能与灵活性,在系统编程、游戏开发等领域占据重要地位。它继承了C语言的高效性,并引入面向对象编程,使代码更模块化易管理。C++支持基本语法如变量声明与控制结构;通过`iostream`库实现输入输出;利用类与对象实现面向对象编程;提供模板增强代码复用性;具备异常处理机制确保程序健壮性;C++11引入现代化特性简化编程;标准模板库(STL)支持高效编程;多线程支持利用多核优势。虽然学习曲线陡峭,但掌握后可开启高性能编程大门。随着新标准如C++20的发展,C++持续演进,提供更多开发可能性。
45 0
|
16天前
|
编译器 Linux C语言
C++基础入门
C++基础入门
|
20天前
|
Rust 安全 C++
系统编程的未来之战:Rust能否撼动C++的王座?
【8月更文挑战第31天】Rust与C++:现代系统编程的新选择。C++长期主导系统编程,但内存安全问题频发。Rust以安全性为核心,通过所有权和生命周期概念避免内存泄漏和野指针等问题。Rust在编译时确保内存安全,简化并发编程,其生态系统虽不及C++成熟,但发展迅速,为现代系统编程提供了新选择。未来有望看到更多Rust驱动的系统级应用。
38 1
|
6天前
|
程序员 C++ 容器
C++编程基础:命名空间、输入输出与默认参数
命名空间、输入输出和函数默认参数是C++编程中的基础概念。合理地使用这些特性能够使代码更加清晰、模块化和易于管理。理解并掌握这些基础知识,对于每一个C++程序员来说都是非常重要的。通过上述介绍和示例,希望能够帮助你更好地理解和运用这些C++的基础特性。
21 0
|
1月前
|
安全 编译器 C++
C++入门 | 函数重载、引用、内联函数
C++入门 | 函数重载、引用、内联函数
25 5
|
1月前
|
存储 安全 编译器
C++入门 | auto关键字、范围for、指针空值nullptr
C++入门 | auto关键字、范围for、指针空值nullptr
49 4
|
1月前
|
编译器 C语言 C++
C++入门 | 命名空间、输入输出、缺省参数
C++入门 | 命名空间、输入输出、缺省参数
33 4
|
1月前
|
编译器 程序员 C语言
C++入门
C++入门
31 5