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 

目录
相关文章
|
18天前
|
存储 C++ UED
【实战指南】4步实现C++插件化编程,轻松实现功能定制与扩展
本文介绍了如何通过四步实现C++插件化编程,实现功能定制与扩展。主要内容包括引言、概述、需求分析、设计方案、详细设计、验证和总结。通过动态加载功能模块,实现软件的高度灵活性和可扩展性,支持快速定制和市场变化响应。具体步骤涉及配置文件构建、模块编译、动态库入口实现和主程序加载。验证部分展示了模块加载成功的日志和配置信息。总结中强调了插件化编程的优势及其在多个方面的应用。
159 61
|
25天前
|
编译器 C++
C++入门12——详解多态1
C++入门12——详解多态1
31 2
C++入门12——详解多态1
|
13天前
|
安全 程序员 编译器
【实战经验】17个C++编程常见错误及其解决方案
想必不少程序员都有类似的经历:辛苦敲完项目代码,内心满是对作品品质的自信,然而当静态扫描工具登场时,却揭示出诸多隐藏的警告问题。为了让自己的编程之路更加顺畅,也为了持续精进技艺,我想借此机会汇总分享那些常被我们无意间忽视却又导致警告的编程小细节,以此作为对未来的自我警示和提升。
|
25天前
|
C++
C++入门13——详解多态2
C++入门13——详解多态2
67 1
|
14天前
|
存储 安全 编译器
【C++打怪之路Lv1】-- 入门二级
【C++打怪之路Lv1】-- 入门二级
15 0
|
14天前
|
自然语言处理 编译器 C语言
【C++打怪之路Lv1】-- C++开篇(入门)
【C++打怪之路Lv1】-- C++开篇(入门)
15 0
|
23天前
|
分布式计算 Java 编译器
【C++入门(下)】—— 我与C++的不解之缘(二)
【C++入门(下)】—— 我与C++的不解之缘(二)
|
23天前
|
编译器 Linux C语言
【C++入门(上)】—— 我与C++的不解之缘(一)
【C++入门(上)】—— 我与C++的不解之缘(一)
|
25天前
|
编译器 C++
C++入门11——详解C++继承(菱形继承与虚拟继承)-2
C++入门11——详解C++继承(菱形继承与虚拟继承)-2
26 0
|
25天前
|
程序员 C++
C++入门11——详解C++继承(菱形继承与虚拟继承)-1
C++入门11——详解C++继承(菱形继承与虚拟继承)-1
31 0