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来定义常量类型


目录
相关文章
|
28天前
|
安全 算法 编译器
【C++ 泛型编程 进阶篇】深入探究C++模板参数推导:从基础到高级
【C++ 泛型编程 进阶篇】深入探究C++模板参数推导:从基础到高级
245 3
|
1月前
|
存储 自然语言处理 Linux
探究C/C++编码世界:从字符编码到中文处理之艺(三)
探究C/C++编码世界:从字符编码到中文处理之艺
43 2
|
1月前
|
自然语言处理 C++
探究C/C++编码世界:从字符编码到中文处理之艺(二)
探究C/C++编码世界:从字符编码到中文处理之艺
37 2
|
1月前
|
存储 自然语言处理 程序员
探究C/C++编码世界:从字符编码到中文处理之艺(一)
探究C/C++编码世界:从字符编码到中文处理之艺
34 1
|
28天前
|
存储 JSON 安全
【C++ JSON库 json值的创建手段】深入探究C++中JSON对象定位与操作:从引用到回调函数
【C++ JSON库 json值的创建手段】深入探究C++中JSON对象定位与操作:从引用到回调函数
61 0
|
4月前
|
编译器 C++ 容器
【C++11特性篇】探究【右值引用(移动语义)】是如何大大提高效率?——对比【拷贝构造&左值引用】
【C++11特性篇】探究【右值引用(移动语义)】是如何大大提高效率?——对比【拷贝构造&左值引用】
|
27天前
|
安全 程序员 C++
【C++ 基本知识】现代C++内存管理:探究std::make_系列函数的力量
【C++ 基本知识】现代C++内存管理:探究std::make_系列函数的力量
101 0
|
27天前
|
XML 运维 监控
【深入探究 C++ 日志库清理策略】glog、log4cplus 和 spdlog 的日志文件管理策略
【深入探究 C++ 日志库清理策略】glog、log4cplus 和 spdlog 的日志文件管理策略
66 0
|
28天前
|
算法 程序员 编译器
【C++ 异常】深入探究C++的stdexcept类库
【C++ 异常】深入探究C++的stdexcept类库
20 0
|
28天前
|
算法 程序员 C++
【C++运算符重载】探究C++中的下标运算符[]重载
【C++运算符重载】探究C++中的下标运算符[]重载
14 0

热门文章

最新文章