c++详解(宏与内联函数,nullptr)

目录

1.宏

2.c++中宏的代替者

3.宏自身的优缺点。

3.1宏的缺点

3.2宏的优点

4.inline

5.使用inline的注意点

6.nullptr

摘要


1.宏

关于宏的定义,不了解的朋友可以点击链接跳转至编译与链接博客,其中预编译部分有详细介绍。

2.c++中宏的代替者

我们知道,c语言中宏可以定义常量,定义函数,虽然在cpp中宏仍可用,但在cpp中我们建议使用

const 、enum(枚举,不了解的朋友可以点击链接跳转至联合体与枚举博客)来代替宏创建常量,用inline(内联)来代替宏函数。

原因在于

3.宏自身的优缺点。

3.1宏的缺点

宏的操作本质上是一个"代替"的操作,在预编译阶段,会对宏进行简单的文本替换,这个特性使得使用宏时要考虑宏的各种副作用(常量的前后置++--等)和各种操作符的优先级 (写宏函数要加各种括号),导致宏函数很复杂还容易出错,因为是文本替换的原因,宏在预处理被展开,宏函数不会建立函数栈帧,这也使得宏函数没法调试

3.2宏的优点

由于宏函数的使用(区别与调用)不需要创建函数栈帧,且高频调用函数的函数结构比较简单,常被写成宏函数,可以节省空间,提高效率

4.inline

用于修饰函数,被inline修饰的函数就叫内联函数,与宏的展开相似,内联函数在编译(在预处理的下一时期,编译的第二阶段,不了解的朋友可以点击链接跳转至编译与链接博客了解编译过程)时,编译器会在调用函数的地方展开成相应的**逻辑汇编代码,**不需要创建函数栈帧,提高效率。因而可以代替宏。

5.使用inline的注意点

  • inline对于编译器来说是一个建议性指令,inline修饰的函数是否被展开,取决于编译器,一般来说代码行数较多的函数,或者递归函数,即使加inline也不会被展开(就是普通的函数)。
  • vs编译器debug版本下,inline默认是不展开的,这样方便调试(展开的话不会创建函数栈帧,无法调试)
  • inline不建议把声明和定义分开在两个文件里,在编译与链接博客中我们知道,在链接时需要把编译阶段产生的符号表进行汇总,并进行符号决议,然后才分配地址内存,如果将声明和定义分开,在没有函数定义的源文件中包含了有函数声明的头文件,在编译时,inline修饰的函数理应展开,但是inline规定,在编译时必须在每个调用点直接会展开,必须在源文件中看到完整的函数定义,只有声明时展不开的,此时会发生编译错误(尝试内联但找不到定义),即使不发生编译错误(取决于编译器),函数成功展开,最后生成的.o文件的符号表中也没有函数的地址(逻辑上内联函数既然已经展开了,也就不需要再去找函数的地址了)(如果定义也在头文件中的话,就能找到函数的地址了,因为定义的第一行的地址就是函数的地址),在链接阶段要汇总编译产生的符号表,进行符号决议和重定位,在符号表中找不到函数地址,会发生链接错误。 总而言之,把inline修饰的函数直接定义在头文件里一点问题都没有!
  • 需要大量调用的函数,不要用内联或者宏,会造成代码的恶性膨胀 ,比如一个用inline修饰的小函数展开后有20行代码,只调用几次,不用建立函数栈帧,确实提高效率,但是要是调用1万次呢,代码量就会剧增,导致项目文件变得非常大,原来1个g的安装包,变成50个g,得不偿失。

6.nullptr

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

cpp 复制代码
#ifndef NULL
    #ifdef __cplusplus
        #define NULL 0
    #else
        #define NULL ((void *)0)
    #endif
#endif

c++中NULL可能被定义为字⾯常量0,或者C中被定义为⽆类型指针(void*)的常量,不论哪边,都有缺陷。

cpp 复制代码
void f(int x)
{
	cout << "f(int x)" << endl;
}

void f(int* ptr)
{
	cout << "f(int* ptr)" << endl;
}

int main()
{
	f(0);//调用上边一个
	f(NULL);//在c++中,想要调用下边函数,但会错调成上边的函数
	//f((void*)0);//c语言中f(NULL);相当于f((void*)0);想调用下边的函数,类型不同,还需要强转
	f(nullptr);//成功调用下边的函数

}

C++11中引⼊nullptr,nullptr是⼀个特殊的关键字,nullptr是⼀种特殊类型的字⾯量,它可以转换
任意其他类型指针 类型,但不能隐式转换成整型,上边的矛盾就可解决。

摘要

本文介绍了C++中宏的替代方案及其优缺点,重点讨论了内联函数(inline)和nullptr的应用。宏在C++中虽仍可使用,但存在副作用和调试困难等问题,建议用const/enum替代宏常量,用inline替代宏函数。内联函数在编译时展开,避免函数调用开销,但不适用于复杂或递归函数,且声明与定义需在同一文件以避免链接错误。此外,宏的优点在于节省空间和提升效率,但过度使用会导致代码膨胀。最后,文章指出C++11引入的nullptr解决了NULL在类型推导中的二义性问题,能明确表示空指针,提升代码安全性。

相关推荐
电商数据girl5 分钟前
如何利用API接口与网页爬虫协同进行电商平台商品数据采集?
大数据·开发语言·人工智能·python·django·json
自由随风飘6 分钟前
旅游城市数量最大化 01背包问题
数据结构·c++·算法·动态规划·旅游
python_13631 分钟前
python设计模式-工厂模式
开发语言·python·设计模式
Warren9835 分钟前
MySQL查询语句详解
java·开发语言·数据库·mysql·算法·蓝桥杯·maven
一只小风华~1 小时前
JavaScript 定时器
开发语言·前端·javascript·vue.js·web
☆璇1 小时前
【C++】stack和queue
开发语言·c++
气质、小青年!1 小时前
【string类常见接口】
c++
hqxstudying1 小时前
Java向量化
java·开发语言
李永奉2 小时前
C语言-字符串(定义)、字符串函数(strlen、strcat、strcpy、strcmp、strlwr、strupr)
c语言·开发语言·算法
暖苏2 小时前
python-异常(笔记)
大数据·开发语言·笔记·python·异常