【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

相关推荐
工具人55551 小时前
Linux远程登录
linux·运维·服务器
郝学胜-神的一滴1 小时前
Python中一切皆对象:深入理解Python的对象模型
开发语言·python·程序人生·个人开发
高洁011 小时前
具身智能-普通LLM智能体与具身智能:从语言理解到自主行动
人工智能·深度学习·算法·aigc·知识图谱
kk哥88991 小时前
Keil MDK 5.39 编程 + 调试 ,ARM 嵌入式开发!如何安装
c++·arm
重启的码农1 小时前
enet源码解析 (2) 对等节点 (ENetPeer)
c++·网络协议
七夜zippoe1 小时前
JVM调优实战:从GC日志分析到参数配置(Xmx, Xms, XX:+)
java·jvm·gc·jit·垃圾回收器
csbysj20201 小时前
JSP 隐式对象
开发语言
星期天21 小时前
3.2联合体和枚举enum,还有动态内存malloc,free,calloc,realloc
c语言·开发语言·算法·联合体·动态内存·初学者入门·枚举enum
塞北山巅2 小时前
camera hal层(AF)
c++·camera