提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
- 前言
- 一、inline
- 二、nullptr
前言
提示:以下是本篇文章正文内容,下面案例可供参考
一、inline
在C++中,inline
关键字是一种函数修饰符,用于建议编译器在编译时将函数的定义直接插入到每个函数调用的地方,而不是进行常规的函数调用。这样做的目的是为了减少函数调用的开销,尤其是对于小型函数来说,因为函数调用涉及到一系列的操作,如保存寄存器、堆栈操作等,这些操作可能会抵消函数体执行的时间。
inline
关键字的主要特点:
-
减少开销:通过避免函数调用的额外开销,
inline
函数可能提高程序的执行效率。 -
多个定义:与普通函数不同,
inline
函数允许在程序中有多个定义点,通常是因为它们在头文件中定义,可以被包含在多个源文件中。 -
编译器优化:
inline
关键字只是一个建议,编译器可以选择忽略它。编译器会根据自己的优化策略和函数的复杂性来决定是否将函数内联。 -
递归限制:通常,递归函数不会被内联,因为内联递归函数可能导致无限的代码膨胀。
-
代码膨胀:过度使用
inline
函数可能导致代码膨胀,即程序的大小增加,这可能会增加内存使用并可能降低性能。 -
模板函数:模板函数默认是内联的,因为它们需要在每个实例化点展开。
inline int add(int a, int b) {return a + b;
}
在这个例子中,add
函数被声明为 inline
,编译器会尝试在每个调用 add
的地方直接替换为 return a + b;
。
注意事项:
- 并不是所有的函数都适合内联。大型函数的内联可能会导致代码膨胀,反而降低性能。
- 编译器的优化技术(如分支预测、循环展开等)可能比内联更有效率。
- 在类定义中使用
inline
关键字可以确保成员函数在头文件中定义时不会引发链接错误。
inline
关键字是C++提供的一种优化手段,但它应该谨慎使用,以确保在提高性能的同时不会带来其他问题。
#include<iostream>
using namespace std;
inline int Add(int x, int y)
{
int ret = x + y;
ret += 1;
ret += 1;
ret += 1;
return ret;
}
int main()
{
// 可以通过汇编观察程序是否展开
// 有call Add语句就是没有展开,没有就是展开了
int ret = Add(1, 2);
cout << Add(1, 2) * 5 << endl;
return 0;
}
二、nullptr
在C++中,nullptr
是一个常量,它表示一个空指针,用于指出没有指向任何对象或函数的指针。nullptr
是 C++11 标准引入的,它提供了一种类型安全的方式来表示空指针,替代了旧式的 NULL
宏和 0
常量。
nullptr
的特点:
-
类型安全:
nullptr
可以匹配任何指针类型,但不会匹配非指针类型。这使得它比NULL
或0
更安全,因为后者可以被隐式转换为任何算术类型。 -
统一表示:
nullptr
提供了一种统一的方式来表示空指针,无论指针的类型如何。 -
显式转换:如果需要,可以将
nullptr
显式转换为任何指针类型,这在需要明确空指针类型的情况下非常有用。 -
初始化:
nullptr
常用于初始化指针变量,表示这些指针在初始化时不指向任何对象。 -
比较操作:
nullptr
可以与任何指针类型进行比较,包括与NULL
或0
比较。 -
模板编程:在模板编程中,
nullptr
可以用于模板函数,因为它具有统一的类型。
#include <iostream>int main() {int* ptr1 = nullptr; // 初始化指针为nullptrdouble* ptr2 = nullptr; // nullptr可以用于任何类型的指针if (ptr1 == nullptr) {std::cout << "ptr1 is null" << std::endl;}// 使用nullptr作为函数参数void function(int* p) {if (p == nullptr) {std::cout << "p is null" << std::endl;}}function(ptr1);return 0;
}
注意事项:
nullptr
不能用于算术运算,因为它不是一个算术类型。nullptr
与NULL
或0
在语义上是等价的,但nullptr
是类型安全的,而NULL
是一个宏,可能被定义为0
或其他值。- 在 C++11 之前的版本中,通常使用
NULL
或0
来表示空指针。
nullptr
是 C++ 中表示空指针的推荐方式,它提供了类型安全和统一的表示方法,使得代码更加清晰和健壮。
#ifndef NULL
#ifdef __cplusplus
#define NULL 0
#else
#define NULL ((void *)0)
#endif
#endif