【C++基础】内联函数、nullptr(内联函数的概念;内联函数VS宏函数;内联函数的特性;C++11中的nullptr)

news2024/10/5 17:16:14

七、内联函数

7.1 内联函数的概念

以inline修饰的函数叫做内联函数,编译时C++编译器会在调用内联函数的地方展开,没有函数调用建立栈帧的开销,内联函数提升程序运行的效率。

应用场景:

  • 短小简单的函数(1-10行),频繁地调用(10万次);
  • 如:堆排和快排进行大数据排序,当中的Swap函数被频繁地调用。

我们可以做以下测试:

  • 普通Add函数:

    在这里插入图片描述

如果在上述函数前增加inline关键字将其改成内联函数,在编译期间编译器会用函数体替换函数的调用。

  • 内联Add函数:

    在这里插入图片描述


7.2 内联函数VS宏函数

宏函数的优缺点:

  • 优点:
    1. 代码的复用性变强
    2. 减少栈帧建立,提高效率

  • 缺点:
    1. 宏函数书写复杂,可读性差
    2. 没有类型安全检查
    3. 不方便调试(因为预编译阶段进行了替换)

内联函数几乎解决了宏函数的所有缺点,并兼具其所有优点。所以内联函数可以完美替代宏函数。

《Effective C++》条款02:尽量以const,enum,inline 替换 #define

  1. 常量定义 换用const,enum
  2. 短小函数定义 换用inline内联函数

7.3 内联函数的特性

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

  2. 为了便于调试,内联函数在debug模式下不会展开。

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

    • 下图为《C++prime》第五版关于inline的建议:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sxLznHry-1681166927629)(C:\Users\zty85\AppData\Roaming\Typora\typora-user-images\image-20230410162042144.png)]

    提示:函数规模较大或是递归函数也展开的话会使汇编指令体量暴增,最后导致编译时间变长,可执行程序变大等问题。

    • 以下是测试代码:
      在这里插入图片描述
  4. inline不建议声明和定义分离,分离会导致链接错误。inline函数会在调用的地方展开,所以符号表中不会有inline函数的符号名(没有函数地址),链接时找不到该函数。

// F.h
#include <iostream>
using namespace std;
inline void f(int i);

// F.cpp
#include "F.h"
void f(int i)
{
	cout << i << endl;
}

// main.cpp
#include "F.h"
int main()
{
	f(10);
	return 0;
}
// 链接错误:main.obj : error LNK2019: 无法解析的外部符号 "void __cdecl
f(int)" (?f@@YAXH@Z),该符号在函数 _main 中被引用

建议:内联函数的定义可以直接写在头文件中。


八、指针空值nullptr(C++11)

8.1 C++98中的指针空值

在良好的C/C++编程习惯中,声明一个变量时最好给该变量一个合适的初始值,否则可能会出现不可预料的错误,比如未初始化的指针。如果一个指针没有合法的指向,我们基本都是按照如下方式对其进行初始化:

void TestPtr()
{
int* p1 = NULL;
int* p2 = 0;
// ……
}

NULL实际是一个宏,在传统的C头文件(stddef.h)中,可以看到如下代码:

#ifndef NULL
#ifdef __cplusplus
#define NULL 0
#else
#define NULL ((void *)0)
#endif
#endif

可以看到,NULL可能被定义为字面常量0,或者被定义为无类型指针(void*)的常量。不论采取何种定义,在使用空值的指针时,都不可避免的会遇到一些麻烦,比如:

void f(int)
{
	cout<<"f(int)"<<endl;
}
void f(int*)
{
	cout<<"f(int*)"<<endl;
}
int main()
{
	f(0);
	f(NULL);
	f((int*)NULL);
	return 0;
}

测试结果:
在这里插入图片描述

  • 程序本意是想通过f(NULL)调用指针版本的f(in*)函数,但是由于NULL被定义成0,因此与程序的初衷相悖。
  • 在C++98中,字面常量0既可以是一个整形数字,也可以是无类型的指针(void*)常量,但是编译器默认情况下将其看成是一个整形常量,如果要将其按照指针方式来使用,必须对其进行强转(void*)0。

8.2 C++11中的nullptr

为了解决上述问题C++11中引入的新概念nullptr,他等价于(void*)0;因此不存在类型混乱的问题。

注意:

  1. 在使用nullptr表示指针空值时,不需要包含头文件,因为nullptr是C++11作为新关键字引入的。
  2. 在C++11中,sizeof(nullptr) 与 sizeof((void*)0)所占的字节数相同。
  3. 为了提高代码的健壮性,在后续表示指针空值时建议最好使用nullptr。

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

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

相关文章

一篇文章把所有前端安全相关的攻击和防御都给解决了——XSS攻击和CSRF攻击

前端安全 1. XSS跨站脚本攻击 1.1 定义 XSS跨站脚本攻击(Cross Site Scripting)&#xff0c;很多人会缩写成CSS&#xff0c;但是这个缩写会与层叠样式表(Cascading Style Sheets,CSS)的缩写混淆&#xff0c;所以&#xff0c;我们通常把跨站脚本攻击缩写成XSS&#xff1b; X…

huggingface transformer模型库使用(pytorch)

参考&#xff1a; https://huggingface.co/docs transformer库 介绍 使用群体&#xff1a; 寻找使用、研究或者继承大规模的Tranformer模型的机器学习研究者和教育者想微调模型服务于他们产品的动手实践就业人员想去下载预训练模型&#xff0c;解决特定机器学习任务的工程师…

初识linux之线程控制

目录 一、POSIX线程库 二、线程创建 1.创建线程的接口 2. 错误的创建多线程 3.正确的创建多线程 4. 线程的私有栈结构 三、线程终止 1. 函数结束 2. 调用pthread_exit&#xff08;&#xff09;终止 3.调用pthread_cancel&#xff08;&#xff09;函数 四、线程等待 …

C++初阶 -1- C++入门

文章目录0.什么是C1.C关键字2.命名空间导入什么是命名空间命名空间的使用3.C 输入&输出4.缺省参数什么是缺省参数缺省参数的应用场景5.函数重载0.什么是C C是基于C语言而产生的&#xff0c;它既可以进行C语言的过程化程序设计&#xff0c;又可以进行以抽象数据类型为特点的…

基于ESP32和blinker的红外小夜灯控制

一. 系统设计及框图&#xff1a; 本设计可以实现通过手机APP使用蓝牙或WIFI远程控制红外设备&#xff0c;也可以通过离线语音模块语音控制红外设备。可以控制市面上常见的NEC格式的红外设备, 这里是控制小夜灯&#xff0c;其它红外设备在控制原理上是相通的。本设计可用作课程…

二、UVM Sequencer和Sequence

了解sequencer与driver之间传递sequence item的握手过程&#xff0c;也掌握了sequence与item之间的关系。接下来对sequence挂载到sequencer的常用方法总结&#xff0c;可以通过这些方法和宏的介绍&#xff0c;了解到它们不同的使用场景面对多个sequence如果需要同时挂到sequenc…

机器学习:基于AdaBoost算法对信用卡精准营销建立模型(附案例实战)

机器学习&#xff1a;基于AdaBoosts算法对信用卡精准营销建立模型 作者&#xff1a;i阿极 作者简介&#xff1a;Python领域新星作者、多项比赛获奖者&#xff1a;博主个人首页 &#x1f60a;&#x1f60a;&#x1f60a;如果觉得文章不错或能帮助到你学习&#xff0c;可以点赞&a…

OPNET Modeler 例程——M/M/1 队列建模

文章目录一、例程概述二、模型构建三、仿真配置及结果1.M/M/1 队列2.M/M/n 队列总结一、例程概述 本例程是使用节点编辑器建立一个 M/M/1 队列模型&#xff0c;同时对仿真收集到的统计数据进行数学分析。M/M/1 队列由先进先出的缓冲区组成&#xff0c;数据包的到达服从指数(泊…

Mybatis动态SQL查询 --(附实战案例--8888个字--88质量分)

目录 前言 一、动态SQL---if标签 1. 持久层添加用户通用查询方法 2. 映射文件添加相关标签 3. 测试类新建测试方法 4. 运行结果 二、动态SQL---where标签 1. 映射文件添加相关标签 2. 测试类新建测试方法 3. 运行结果 三、动态SQL---set标签 1. 持久层添加用户更新方…

DNS域名协议(IP段获取DNS服务器、反解析获取主机域名、查找子域名记录、查看子域名记录)

IP段获取DNS服务器 nmap 192.168.190.0/24 -p53 反解析获取主机域名 host 192.168.137.149 192.168.137.149 查找子域名记录 dig 192.168.137.149 -t axfr MAILMAN.com 查看子域名记录 dig 192.168.137.149 -t axfr _msdcs.MAILMAN.com

神经微分方程Resnet变体实现内存下降和保持精度

本文内容&#xff1a; 1、学习神经微分方程的笔记&#xff0c;主要锻炼自己学习新知识的能力和看有很多数学原理的论文能力&#xff1b; 2、神经微分方程可以用于时序数据建模、动力学建模等&#xff0c;但是本文专注于分类问题-resnet变体<比较容易理解>&#xff1b; …

StringBuffer,StringBuilder,

StringBuffer 结构示意图&#xff0c; Serializable,可以实现网络传输 package com.jshedu.StringBuffer_;/*** author Mr.jia* version 1.0*/public class StringBuffer01 {public static void main(String[] args) {/*1.在父类中AbstractStringBuilder 属性char[] value不是f…

博弈论在电动车和电网系统中分布式模型预测控制研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

Android中使用有趣的指示器和过渡自定义 Compose Pager

Android使用有趣的指示器和过渡自定义 Compose Pager google最近在compose中新增了Pager控件&#xff0c;HorizontalPager和VerticalPager。 页面之间的转换 该文档涵盖了访问页面从“对齐”位置滚动到多远的基础知识。我们可以使用这些信息来创建页面之间的过渡效果。 例…

DC:4通关详解

信息收集 漏洞发现 访问web 尝试弱口令 账号admin 可以执行ls du df看看发的包,我们是否有机会执行任意命令 发现post传参radio处可以任意命令执行 弹个shell先 提权 从vps上下载LinEnum.sh来枚举脆弱性 优化shell 现在shell就有自动补齐了 在/home/jim下发现密码字典…

cube-studio AI平台 提供开源模型示例列表(3月份)

文章目录背景AI应用商店背景 cube是腾讯音乐开源的一站式云原生机器学习平台&#xff0c;目前主要包含 1、数据管理&#xff1a;特征存储、在线和离线特征&#xff1b;数据集管理、结构数据和媒体数据、数据标签平台 2、开发&#xff1a;notebook(vscode/jupyter)&#xff1b…

【PTA天梯赛】L1-001 L1-002 L1-003 L-004 L-005 L-006 L-007 L-008 L-009 L1-010 c++

&#x1f680; 个人简介&#xff1a;CSDN「博客新星」TOP 10 &#xff0c; C/C 领域新星创作者&#x1f49f; 作 者&#xff1a;锡兰_CC ❣️&#x1f4dd; 专 栏&#xff1a;狠狠的刷题&#xff01;&#xff01;&#xff01;&#x1f308; 若有帮助&#xff0c;还请…

【Ubuntu 22.04 上配置 FTP 服务器步骤】

Ubuntu 22.04 上配置 FTP 服务器步骤 1.安装 vsftpd 软件包&#xff1a; sudo apt-get update sudo apt-get install vsftpd 2.查看vsftpd版本和状态&#xff0c;确认vsftpd安装成功和正常启动 2.修改 vsftpd 配置文件&#xff1a; sudo nano /etc/vsftpd.conf 3.在配置文件中…

Ethercat概念学习

Ethercat技术调研 背景 最近我们要基于Ethercat技术进行开发&#xff0c;首先需要了解其基本原理&#xff0c;github上看到了有相关实现&#xff0c;一起来看看吧。 Ethercat技术 速度更快 传输速率:2*100 Mbaud 全双工 高速性、高实时性 微秒级 像火车一样有帧头、帧尾&a…

如何对农田温室气体进行有效模拟?

农业是甲烷&#xff08;CH4&#xff09;、氧化亚氮&#xff08;N2O&#xff09;和二氧化碳&#xff08;CO2&#xff09;等温室气体的主要排放源&#xff0c;占全产业排放的13.5%。农田温室气体又以施肥产生的N2O和稻田生产产生的CH4为主&#xff0c;如何对农田温室气体进行有效…