龙空技术网

内联函数、宏定义和const区别

远点Faraway 270

前言:

今天你们对“c语言宏变长”可能比较着重,姐妹们都想要了解一些“c语言宏变长”的相关资讯。那么小编在网上搜集了一些关于“c语言宏变长””的相关内容,希望咱们能喜欢,兄弟们一起来学习一下吧!

函数体被编译成对应的一段汇编代码,在符号表中会生成一个函数名指向这段代码的入口地址。所有调用此函数的地方都会被编译成CALL函数名指令,然后连接时将函数名替换为函数的入口地址。

1. 内联函数1.1. 内联函数

即通过inline关键字将一个函数定义为内联函数,当编译器发现某段代码在调用一个内联函数时,其会将该函数的代码整段的插入到当前位置,这样的好处是省去了压栈出栈等函数调用过程,从而加快了程序的运行速度。但是缺点就是每当代码调用该函数,就会在调用处插入该代码段,导致程序的体积增大。而且如果内联函数过于复杂,编译器可能将其视为普通函数。

1.2. 内联函数需要注意 含有递归调用自己的函数不能为inline;使用了循环/switch等复杂语句的函数不能为inline; 由于inline会增加代码的体积,所以最好该函数代码量不超过5行;只要在函数的定义前面加了inline,那么就是内联函数,仅仅在声明前加则不是; 内联函数需要将函数声明和定义都放入头文件中,如果仅仅放入声明,那么编译器找不到函数实现将无法实现替换;1.3. C++类中的内联函数 定义在类中成员函数一定是内联函数(即使不手动写inline);显示定义在类中的成员函数一定是内联函数;在类中显示声明为inline,同时在类外定义的函数是内联函数;在类中没有显示声明为inline,在类外定义成了inline则也是内联函数;如果一个成员函数在类中声明不是inlie,则类外定义也不是inline则其不是内联函数;2. 宏定义

所谓宏定义即,程序运行用一个标识符来表示另外一个表达式(可以是常量,变量,字符串,函数等),宏定义在程序编译预处理时被替换。

2.1. 宏定义的优点

可以用宏定义来替换程序中经常使用的一些常量,这样当某个常量需要修改时,直接修改宏定义即可,这样很方便,而且也提高了程序的可读性。

可以用带参的宏定义来完成函数调用的功能,从而减少系统开销(函数调用会存在压栈出栈等保留函数现场和回复函数现场的操作),对于一些简单的函数调用可能就几条语句,那么函数调用所带来的开销将很大,所以用宏定义会直接在预处理阶段在函数调用处展开,从而提高程序执行效率。

2.2. 宏定义的缺点宏定义在代码处直接替换展开,可能导致程序较大;宏定义无法调试;对于带参的宏定义,由于直接替换,不会检查参数的合法性,存在安全隐患;2.3. 宏定义和全局变量宏定义在预编译期使用和替换,全局变量则是在运行时,全局变量在编译时初始化;宏定义在编译时被替换到引用的位置,而变量则是在运行时分配空间;宏定义不可被赋值,其值定义后不可被修改,而变量运行时可以修改;宏定义只有在定义所在文件,或者引用所在文件的其他文件中使用(即在头文件中定义的宏可以在包含头文件的源文件中使用,但是源文件中定义的宏,只能该文件使用),而全局变量则是在工程所有文件中使用;2.4. 宏定义和函数调用宏定义直接在调用处展开,不占用函数调用的时间,效率更高(但是要占用编译的时间);宏定义只是简单的字符替换,不存在传参和返回值的概念;宏定义不存在类型问题,宏名无类型,其参数也无类型,只是一个符号代表,展开时带入指定的字符即可,但是同样也就没有类型检查,可能不安全;宏定义在所有函数调用处展开,可能导致源程序变长;宏定义不能调试;宏定义只是简单的字符替换,所以要多加括号,避免因为优先级而引起的各种问题;2.5. 宏定义和const宏定义在预处理阶段展开,const则是在编译运行阶段使用;宏定义没有类型,不做类型检查,const是有具体的类型的,在编译阶段会检查;宏定义只是进行展开,有多少地方使用,就替换多少次(占用代码段空间),它定义的宏常量在内存中有若干备份;const定义的常量在程序运行过程中只存在一份(占用常量数据区空间),从而const节省了空间,避免不必要的空间浪费;宏定义不能调试,而const可以调试;const不能重复定义某个变量,但是define可以通过undef取消某个符号的定义,然后重新定义;2.6. 宏定义和内联函数宏定义由预处理器处理,进行简单的文本替换,而内联函数则是由编译器处理,直接将编译后的函数体插入调用的地方;宏定义不可调试,但是内联函数可以调试; 内联函数的参数有类型检查,而宏定义没有;宏定义可以定义常量,但是内联函数只能是函数;

标签: #c语言宏变长