C/C++中#define的探究

简介: 一. #define简介 1. #define命令是宏定义命令,主要在预编译的时候进行字符替换,把宏名用宏体进行替换 2. 预编译的主要工作主要是进行代码文本的替换工作,用于处理#开头的指令,包括#Include、#define、#ifdef、#endif等等,预编译的工作只是纯粹的替换与展开,没有任何的计算功能 二. #define命令的缺陷 1. 无法进行类型检查。


一. #define简介

1. #define命令是宏定义命令,主要在预编译的时候进行字符替换,把宏名用宏体进行替换

2. 预编译的主要工作主要是进行代码文本的替换工作,用于处理#开头的指令,包括#Include、#define、#ifdef、#endif等等,预编译的工作只是纯粹的替换与展开,没有任何的计算功能


二. #define命令的缺陷

1. 无法进行类型检查。宏定义是在编译之前进行的字符替换,因为还没有编译所以不能在编译之前就进行检查类型是否匹配,而只能在编译时候才知道,所以无法进行类型检查

2. 由于优先级的不同,在进行宏定义的时候可能存在副作用。比如#define Add(a,b) a+b,这个时候直接把宏体替换掉的时候可能会存在问题,正确的写法是#define Add(a,b) ((a)+(b))

3. 会导致代码膨胀。由于宏定义是进行文本替换,需要对代码进行展开,因此多处使用宏定义会存在冗余代码


三. 含参数的宏和函数的区别

1. 函数调用的时候首先求出实参表达式的值,然后带入形参。宏定义只是进行简单的字符替换

2. 函数调用过程是在程序运行的时候,它需要分配临时的内存单元。宏展开是在预编译的时候,不需要分配内存单元

3. 函数参数存在类型问题;宏中不存在类型问题,展开的时候带入指定的字符即可

4. 宏展开多次使得源程序会变得很长,而函数调用是不会使源程序变长的

5. 宏展开是不占运行时间的,而函数调用需要占运行时间


四. 宏展开隐藏的问题

下面这个程序

#define Y(n) (4*n)

int main(){
      int a = Y(5+1); 
      printf("%d\n", a);
      return 0;
}

输出结果是21,为什么不是24?

因为宏定义的原因Y(5+1) = (4*5+1),这个时候实际上是把n用5+1来替换,所以就得到了21。


五. #define和const的区别

define和const都能够定义常量,define既可以替代常数值,又可以替代表达式,甚至是代码段,但是比较容易出错。const的引入可以增强程序的可读性,使程序的维护与调试变的更加方便。

1. define只是用来进行单纯的文本替换,define常量的生命周期止于编译期,不分配内存空间,它存在于程序代码区,在实际的程序中只是一个常数

    const常量存在于程序的常量区,const常量在程序中确实存在,可以被调用和传递

2. const常量是有数据类型的,而define常量没有数据类型

3. 编译器会对const常量进行类型检查,define是在预编译时候进行替换不会进行类型检查

   const常量保护程序中的常量不被修改,而且对数据类型也会进行检查,提高了程序的健壮性,所以一般用const来定义常量类型


目录
相关文章
|
6月前
|
编译器 API C语言
深入探究Qt与C++标准的兼容之旅
深入探究Qt与C++标准的兼容之旅
579 3
|
6月前
|
存储 编译器 C语言
【C/C++ 函数返回的奥秘】深入探究C/C++函数返回:编译器如何处理返回值
【C/C++ 函数返回的奥秘】深入探究C/C++函数返回:编译器如何处理返回值
608 3
|
6月前
|
安全 算法 编译器
【C++ 泛型编程 进阶篇】深入探究C++模板参数推导:从基础到高级
【C++ 泛型编程 进阶篇】深入探究C++模板参数推导:从基础到高级
703 3
|
6月前
|
存储 算法 编译器
【C++ 函数尾部返回】C++中的尾返回类型:探究auto func() -> ReturnType的魔力
【C++ 函数尾部返回】C++中的尾返回类型:探究auto func() -> ReturnType的魔力
178 1
|
6月前
|
消息中间件 负载均衡 监控
【ZMQ PUB模式指南】深入探究ZeroMQ的PUB-SUB模式:C++编程实践、底层原理与最佳实践
【ZMQ PUB模式指南】深入探究ZeroMQ的PUB-SUB模式:C++编程实践、底层原理与最佳实践
1845 1
|
6月前
|
存储 监控 安全
【深入探究C++日志库写入策略】glog、log4cplus与spdlog的写入策略比较
【深入探究C++日志库写入策略】glog、log4cplus与spdlog的写入策略比较
541 0
|
6月前
|
存储 JSON 安全
【C++ JSON库 json值的创建手段】深入探究C++中JSON对象定位与操作:从引用到回调函数
【C++ JSON库 json值的创建手段】深入探究C++中JSON对象定位与操作:从引用到回调函数
158 0
|
6月前
|
安全 程序员 编译器
【C/C++ 泛型编程 进阶篇 Type traits 】C++类型特征探究:编译时类型判断的艺术
【C/C++ 泛型编程 进阶篇 Type traits 】C++类型特征探究:编译时类型判断的艺术
474 1
|
6月前
|
消息中间件 算法 Java
C++实时通信优化技术探究
C++实时通信优化技术探究
69 3
|
6月前
|
算法 Linux 编译器
⭐⭐⭐⭐⭐Linux C++性能优化秘籍:从编译器到代码,探究高性能C++程序的实现之道
⭐⭐⭐⭐⭐Linux C++性能优化秘籍:从编译器到代码,探究高性能C++程序的实现之道
439 2