[C++]内联函数和nullptr

 
> 🍃 本系列为初阶C++的内容,如果感兴趣,欢迎订阅🚩
> 🎊个人主页:[小编的个人主页])小编的个人主页
>  🎀   🎉欢迎大家点赞👍收藏⭐文章
> ✌️ 🤞 🤟 🤘 🤙 👈 👉 👆 🖕 👇 ☝️ 👍


目录

🐼inline

 🐼nullptr


🐼inline

  • 🌟在C语言阶段,我们学习了宏,并学习了宏函数的用法。比如写一个加法的宏函数:#define Add(x,y) ((x)+(y))由于C语言宏函数的容易出错,不一小心就会使逻辑错误,比如:为什么不能加分号?为什么要加外层括号?为什么要加内层括号?而且宏函数还不能调试(都是在编译期间已经完成替换)。如果在这里发生逻辑错误,我们很难发现。所以C++设计了inline目的就是替代C的宏函数。
  • 所以在C++中,引入了内联函数(inline)用inline修饰的函数叫做内联函数,在编译区间,编译器会将内联函数展开,这样就不需要建立函数栈帧,提高了效率
  • 需要注意vs编译器debug版本下面默认是不展开inline的,目的是方便调试,debug版本想展开需要设置⼀下以下两个地方。

 第一步:

   

第二步:

  

我们可以从汇编层看内联函数是否展开 

对于这段内联函数:

#define  _CRT_SECURE_NO_WARNINGS
#include <malloc.h>
#include<iostream>
using namespace std;
inline int Add(int x, int y)
{int ret = x + y;ret += 1;return ret;
}
#include"F.h"
int main()
{// 可以通过汇编观察程序是否展开 // 有call Add语句就是没有展开,没有就是展开了 int ret = Add(1, 2);cout << Add(1, 2) * 5 << endl;return 0;
}

没设置之前:

  

我们发现,内联函数发生了调用,没有展开,说明vs默认是不展开的。

通过刚刚两步设置修改后:

  

✨经过修改,我们发现,在vs中,编译器默认不展开inline函数,而我们修改后,inline函数在编译期间直接展开。 

  •  🌟inline对于编译器而言只是⼀个建议,也就是说,你加了inline编译器也可以选择在调用的地方不展开,不同编译器关于inline什么情况展开各不相同,因为C++标准没有规定这个。inline适用于频繁调用的短小函数,对于递归函数,代码相对多⼀些的函数,加上inline也会被编译器忽略。具体最后inline函数是否展开取决于编译器
  • inline不建议声明和定义分离到两个文件,分离会导致链接错误。因为inline被展开,就没有函数地址,链接时会出现报错。 对于编译器而言,编译器回去找函数的地址,但是内联函数如果展开,在链接期间:在符号表中是默认不存在的,所以编译器找不到内联函数的首地址,发生了链接错误。

如: 

//test.cpp#include"F.h"int main()
{// 可以通过汇编观察程序是否展开 // 有call Add语句就是没有展开,没有就是展开了 int ret = Add(1, 2);cout << Add(1, 2) * 5 << endl;f(1);//call(0x)//f();return 0;
}#pragma once
// F.h
#include <iostream>
using namespace std;
inline void f(int i);//F.cpp
#define  _CRT_SECURE_NO_WARNINGS
// F.cpp
#include "F.h"
inline void f(int i)
{cout << i << endl;
}

会发生链接错误,编译器报错: "void __cdecl f(int)" (?f@@YAXH@Z),函数 main 中引用了该符号.这正是因为内联函数的声明和定义分开,导致的。

 🐼nullptr

🌟在C语言中,NULL本质上是宏。

但是C++中NULL可能被定义为字面常量0,或者C中被定义为无类型指针(void*)的常量。不论采取何种定义,在使用空值的指针时,都不可避免的会遇到一些麻烦,本想通过f(NULL)调用指针版本的 f(int*)函数,但是由于NULL被定义成0,调用了f(intx),因此与程序的初衷相悖。f((void*)NULL); 调用会报错。

如:


#include<iostream>
using namespace std;
void f(int x)
{cout << "f(int x)" << endl;
}
void f(int* ptr)
{cout << "f(int* ptr)" << endl;
}
int main()
{f(0);// 本想通过f(NULL)调⽤指针版本的f(int*)函数,但是由于NULL被定义成0,调⽤了f(int x),因此与程序的初衷相悖。f(NULL);f((int*)NULL);// 编译报错:error C2665: “f”: 2 个重载中没有⼀个可以转换所有参数类型 // f((void*)NULL);f(nullptr);return 0;
}

运行结果:

f(int x)
f(int x)
f(int* ptr)
f(int* ptr)

C++11中引入nullptr,nullptr是⼀个特殊的关键字,nullptr是⼀种特殊类型的字面量,它可以转换成任意其他类型的指针类型。使用nullptr定义空指针可以避免类型转换的问题,因为nullptr只能被隐式地转换为指针类型,而不能被转换为整数类型

 感谢你看到这里,如果觉得本篇文章对你有帮助,点个赞👍 吧,你的点赞就是我更新的最大动力⛅️🌈 ☀️

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/59142.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

15分钟学 Go 实战项目三 : 实时聊天室(学习WebSocket并发处理)

实时聊天室&#xff1a;学习WebSocket并发处理 目标概述 在本项目中&#xff0c;我们将创建一个实时聊天室&#xff0c;使用Go语言和WebSocket来处理并发消息交流。这将帮助你深入理解WebSocket协议的工作原理以及如何在Go中实现并发处理。 1. 项目需求 功能需求 用户可以…

thinkphp6 使用workerman扩展开发tcp应用

代码 <?phpnamespace app\shop\controller;use think\worker\Server;class Tcp extends Server {protected $socket tcp://127.0.0.1:12345;protected $option [name > "order_tcp",count > 1,pidFile > worker.pid, // daemonize > true,…

工业4.0时代下的人工智能新发展

摘要&#xff1a;随着德国工业4.0时代以及中国制造2025的提出&#xff0c;工业智能化的改革的时代正逐渐到来&#xff0c;然而我国整体工业水平仍然处于工业2.0水平。围绕工业4.0中智能工厂、智能生产、智能物流这三大主题&#xff0c;结合国内外研究现状&#xff0c;对人工智能…

一步一步从asp.net core mvc中访问asp.net core WebApi

"从asp.net core mvc中访问asp.net core WebApi"看到这个标题是不是觉得很绕口啊&#xff0c;但的确就是要讲一讲这样的访问。前面我们介绍了微信小程序访问asp.net core webapi(感兴趣的童鞋可以看看前面的博文有关WEBAPI的搭建)&#xff0c;这里我们重点不关心如何…

【Python】关于python中overload装饰器详解

Python不像C、Java等语言可以进行函数的重载。Python是不可以进行函数重载的。下面的例子&#xff0c;虽然我们定义了三个test函数&#xff0c;但是在局部命名空间下&#xff0c;只有一个test函数&#xff0c;就是最有一个&#xff0c;也就是说最后一个test覆盖了前两个test。 …

Qt 获取当前系统中连接的所有USB设备的信息 lsusb版

Qt 获取当前系统中连接的所有USB设备的信息 lsusb版 flyfish 环境 Ubuntu22.04 Qt 6.2.4 实现的功能 枚举USB设备&#xff1a;使用lsusb命令获取当前系统中连接的所有USB设备的信息。 解析设备信息&#xff1a;将lsusb命令的输出按行分割&#xff0c;并提取每行中的总线号、…

使用git进行多人协作开发项目流程

使用git进行多人协作开发项目流程 当然&#xff0c;以下是一个整合了分支管理、Pull Request流程以及日常Git操作的完整GitHub多人协作开发教程。这个教程将从仓库的创建和设置开始&#xff0c;一直到开发流程和最终的代码合并&#xff0c;形成一个完整的工作流程。 完整的Gi…

[面试]Mysql的锁机制

一、锁的基本概念 MySQL中的锁主要用于控制多个事务对数据库资源的并发访问&#xff0c;以确保数据的一致性和完整性。锁机制是数据库并发控制的核心&#xff0c;通过锁定数据库中的资源来防止并发操作引发的数据冲突。 二、锁的分类 MySQL的锁按照作用范围可以分为表级锁和行…

计算2000-2100年,阳历11月11日,与阴历10月1日重叠的年份

# 计算2000-2100年&#xff0c;阳历11月11日&#xff0c;与阴历10月1日重叠的年份from datetime import datetime from lunardate import LunarDatedef find_matching_years(start_year, end_year):matching_years []for year in range(start_year, end_year 1):solar_date …

JVM学习之路(5)垃圾回收

目录 Java垃圾回收 方法区回收 方法区的回收 堆内存回收 引用计数法和可达性分析算法 查看GC Root 五种对象引用 软引用 ​编辑 弱引用 虚引用和终结器引用 垃圾回收算法&#xff1a; 垃圾回收算法的历史和分类 垃圾回收算法的评价标准 标记清除算法 复制算法 标记整理算法 分代…

ubuntu 20.04 NVIDIA驱动、cuda、cuDNN安装

1. NVIDIA驱动 系统设置->软件和更新->附加驱动->选择NVIDIA驱动->应用更改。该界面会自动根据电脑上的GPU显示推荐的NVIDIA显卡驱动。 运行nvidia-smi: NVIDIA-SMI has failed because it couldnt communicate with the NVIDIA driver. Make sure that the lat…

docker如何实时查看项目的日志

1. 使用docker logs命令 基本语法和原理&#xff1a;docker logs命令用于获取容器的日志输出。默认情况下&#xff0c;它会显示容器启动后到当前时间的所有日志内容。当你在容器内的应用程序将日志输出到标准输出&#xff08;stdout&#xff09;或标准错误输出&#xff08;std…

Ubuntu18.04+ROS环境+moveit UR5机械臂仿真

目录 仿真环境&#xff1a; 1.下载Universal Robots机器人功能包 2.运行 Gazebo中的仿真模型 3.运行moveit运动规划 4.运行rviz并进行轨迹规划 仿真环境&#xff1a; 本文使用版本&#xff1a;Ubuntu18.04 ros版本&#xff1a;ros-melodic-desktop-full&#xff0c;安装…

C++11新特性(二)

目录 一、C11的{} 1.初始化列表 2.initializer_list 二、可变参数模版 1.语法与原理 2.包扩展 3.empalce接口 三、新的类功能 四、lambda 1.语法 2.捕捉列表 3.原理 五、句装器 1.function 2.bind 一、C11的{} 1.初始化列表 C11以后想统⼀初始化⽅式&#xff0…

python获取iOS最近业务日志的两种方法

当iOS UI自动化用例执行失败的时候&#xff0c;需要获取当时的业务日志&#xff0c;供后续分析使用。 现在已经把iOS沙盒目录挂载到本地&#xff0c;剩下的事情就是从沙盒目录中捞取当前的日志&#xff0c;沙盒中的日志文件较大&#xff0c;整体导出来也可以&#xff0c;但是会…

Flutter 小技巧之 Shader 实现酷炫的粒子动画

在之前的《不一样的思路实现炫酷 3D 翻页折叠动画》我们其实介绍过&#xff1a;如何使用 Shader 去实现一个 3D 的翻页效果&#xff0c;具体就是使用 Flutter 在 3.7 开始提供 Fragment Shader API &#xff0c;因为每个像素都会过 Fragment Shader &#xff0c;所以我们可以通…

实现3D热力图

实现思路 首先是需要用canvas绘制一个2D的热力图&#xff0c;如果你还不会&#xff0c;请看json绘制热力图。使用Threejs中的canvas贴图&#xff0c;将贴图贴在PlaneGeometry平面上。使用着色器材质&#xff0c;更具json中的数据让平面模型 拔地而起。使用Threejs内置的TWEEN&…

风险数据集市整体架构及技术实现

引言 在当今大数据时代&#xff0c;风险数据集市作为金融机构的核心基础设施之一&#xff0c;扮演着至关重要的角色。它不仅为银行、保险等金融机构提供了全面、准确的风险数据支持&#xff0c;还帮助这些机构实现了风险管理的精细化和智能化。本文将深入探讨一种基于大数据La…

使用k8s RBAC和ValidatingAdmissionPolicy 配合来校验用户权限

我先讲一下业务场景&#xff1a; k8s集群内部有几个重要的命名空间&#xff08;比如&#xff1a; kube-system, kube-public 等&#xff09;&#xff0c;这些命名空间除了管理员有权限&#xff0c;其他用户不可以操作&#xff08;编辑&#xff0c;删除&#xff09;这几个命名空…

2. Sharding-JDBC广播表和绑定表操作

1. 广播表实战 ⼴播表概念 1. 指所有的分⽚数据源中都存在的表&#xff0c;表结构和表中的数据在每个数据库中均完全⼀致。 2. 适⽤于数据量不⼤且需要与海量数据的表进⾏关联查询的场景。 3. 例如&#xff1a;字典表、配置表。注意 1. 分库分表中间件&#xff0c;对应的数据…