【C++】C++入门 -- inline、nullptr

🫧个人主页:小年糕是糕手

💫个人专栏:《C++》《数据结构(初阶)》《C/C++刷题集》《C语言》

🎨你不能左右天气,但你可以改变心情;你不能改变过去,但你可以决定未来!



目录

一、inline

二、nullptr

2.1、nullptr的本质

[2.2、为什么需要 nullptr?(NULL 的问题)](#2.2、为什么需要 nullptr?(NULL 的问题))

2.3、使用建议


一、inline

  • 用 inline 修饰的函数叫做内联函数,编译时 C++ 编译器会在调用的地方展开内联函数,这样调用内联函数就不需要建立栈帧了,就可以提高效率。
  • inline 对于编译器而言只是一个建议,也就是说,你加了 inline 编译器也可以选择在调用的地方不展开,不同编译器关于 inline 什么情况展开各不相同,因为 C++ 标准没有规定这个。inline 适用于频繁调用的短小函数,对于递归函数,代码相对多一些的函数,加上 inline 也会被编译器忽略。
  • C 语言实现宏函数也会在预处理时替换展开,但是宏函数实现很复杂很容易出错的,且不方便调试,C++ 设计了 inline 目的就是替代 C 的宏函数。
  • vs 编译器 debug 版本下面默认是不展开 inline 的,这样方便调试,debug 版本想展开需要设置一下以下两个地方。
  • inline 不建议声明和定义分离到两个文件,分离会导致链接错误(直接定义到.h文件中)。因为 inline 被展开,就没有函数地址,链接时会出现报错。
cpp 复制代码
#define _CRT_SECURE_NO_WARNINGS 1

//宏坑很多
//C++建议 const enum inline替代宏
//ADD的宏函数
//宏替换(宏是一种机制替换)
//#define ADD(int a,int b) return a + b;
//#define ADD(a, b) a + b
//#define ADD(a, b) (a + b);
#define ADD(a, b) ((a)+(b))
//宏函数很复杂,容易写出问题,还不能调试
//优点: 高频度调用小函数,写成宏函数,可以提高效率,
//预处理阶段宏会替换,提高效率,不建立栈帧
#include<iostream>
using namespace std;
//默认debug版本下,inline也不展开,为了方便调试
//这里加上inline,这就叫内联函数,下面我们使用这个函数就不是函数调用了(编译器会处理)
//内联缺陷: 代码指令膨胀,可执行程序(安装包)变大
//// 可以通过汇编观察程序是否展开 

inline int Add(int x, int y)
{
	return x + y;
    // 可以通过汇编观察程序是否展开 
    // 有call Add语句就是没有展开,没有就是展开了 
}
int main()
{
	int ret1 = ADD(1, 2);//int ret = 1 + 2;
	cout << ret1 << endl;

	int ret2 = ADD(1, 2) * 3;
	cout << ret2 << endl;
	
	//a和b是表达式,表达式中的运算符比+优先级低
	int x = 0, y = 1;
	ADD(x | y, x & y);// ((x | y) + (x & y));
}


这里我们可以举个例子:inline Func函数,展开后是20行指令,10000个调用的位置:

展开需要多少行指令:10000*20

不展开需要多少行指令:10000+20

二、nullptr

2.1、nullptr的本质

C++11 引入的 空指针专用字面量 ,是一种特殊类型(std::nullptr_t),专门用于表示 "空指针",解决了传统 NULL 的缺陷。

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

2.2、为什么需要 nullptr?(NULL 的问题)
  • C++ 中 NULL 可能被定义为字面常量 0,或者 C 中被定义为无类型指针 (void*) 的常量。不论采取何种定义,在使用空值的指针时,都不可避免的会遇到一些麻烦,本想通过 f (NULL) 调用指针版本的 f (int*) 函数,但是由于 NULL 被定义成 0,调用了 f (int x),因此与程序的初衷相悖。f ((void*) NULL); 调用会报错。
  • C++11 中引入 nullptr,nullptr 是一个特殊的关键字,nullptr 是一种特殊类型的字面量,它可以转换成任意其他类型的指针类型。使用 nullptr 定义空指针可以避免类型转换的问题,因为 nullptr 只能被隐式地转换为指针类型,而不能被转换为整数类型。
cpp 复制代码
#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;
}
cpp 复制代码
void f(int x) { cout << "int 版本" << endl; }
void f(int* p) { cout << "指针版本" << endl; }

int main() {
    f(NULL);    // 实际调用 f(int),而非预期的 f(int*)(因为 NULL 被解析为 0)
    f(nullptr); // 正确调用 f(int*),无歧义
    return 0;
}
2.3、使用建议
  1. C++11 及以上版本,优先使用 nullptr 表示空指针 ,彻底替代 NULL,避免歧义。

  2. 不要将 nullptr 与整数直接比较(如 if (nullptr == 0) 编译报错),仅用于指针的空值判断:

    cpp 复制代码
    int* p = nullptr;
    if (p == nullptr) { ... } // 正确(判断指针为空)
  3. 若需兼容 C 语言代码(C 无 nullptr),可保留 NULL;纯 C++ 项目建议全面替换为 nullptr

相关推荐
Boilermaker19926 小时前
[Java 并发编程] Synchronized 锁升级
java·开发语言
MM_MS6 小时前
Halcon变量控制类型、数据类型转换、字符串格式化、元组操作
开发语言·人工智能·深度学习·算法·目标检测·计算机视觉·视觉检测
C_心欲无痕6 小时前
ts - tsconfig.json配置讲解
linux·前端·ubuntu·typescript·json
独自破碎E7 小时前
【二分法】寻找峰值
算法
꧁Q༒ོγ꧂7 小时前
LaTeX 语法入门指南
开发语言·latex
njsgcs7 小时前
ue python二次开发启动教程+ 导入fbx到指定文件夹
开发语言·python·unreal engine·ue
alonewolf_997 小时前
JDK17新特性全面解析:从语法革新到模块化革命
java·开发语言·jvm·jdk
冰西瓜6007 小时前
国科大2025操作系统高级教程期末回忆版
linux
mit6.8247 小时前
位运算|拆分贪心
算法
古城小栈7 小时前
Rust 迭代器产出的引用层数——分水岭
开发语言·rust