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在类型推导中的二义性问题,能明确表示空指针,提升代码安全性。

相关推荐
时光找茬1 分钟前
【瑞萨AI挑战赛-FPB-RA6E2】+ 从零开始:FPB-RA6E2 开箱测评与 e2 studio 环境配置
c++·单片机·边缘计算
qq_537562671 分钟前
跨语言调用C++接口
开发语言·c++·算法
wjs202412 分钟前
DOM CDATA
开发语言
Tingjct13 分钟前
【初阶数据结构-二叉树】
c语言·开发语言·数据结构·算法
猷咪39 分钟前
C++基础
开发语言·c++
IT·小灰灰41 分钟前
30行PHP,利用硅基流动API,网页客服瞬间上线
开发语言·人工智能·aigc·php
快点好好学习吧42 分钟前
phpize 依赖 php-config 获取 PHP 信息的庖丁解牛
android·开发语言·php
秦老师Q43 分钟前
php入门教程(超详细,一篇就够了!!!)
开发语言·mysql·php·db
烟锁池塘柳043 分钟前
解决Google Scholar “We‘re sorry... but your computer or network may be sending automated queries.”的问题
开发语言
是誰萆微了承諾43 分钟前
php 对接deepseek
android·开发语言·php