当前位置: 首页 > article >正文

define,typedef,inline 的区别

define

1.用于在代码中创建宏定义,将一个标识符替换为一个表达式或语句。例如:

#define PI 3.14159
#define SQUARE(x) ((x) * (x))

这样,程序中所有出现的 PI 都将被替换为 3.14159,SQUARE(x) 则被替换成了 (x) * (x)

使用 #define 定义宏和使用函数定义是有很大区别的。使用 #define 定义宏只是简单的文本替换,没有类型检查和语法分析,而函数定义则会进行类型检查、语法分析,并分配栈空间存储局部变量和函数参数等信息。因此,使用函数定义更加安全和可靠,而使用宏定义则可以更灵活地编写代码。

类型检查是指编译器在编译程序的过程中对变量、表达式、函数参数和返回值等数据类型的正确性进行检查。如果程序中存在类型不匹配的情况,编译器会给出警告或错误提示。通过类型检查,可以帮助程序员避免一些常见的编程错误,例如类型不匹配、越界访问、空指针引用等等。

2. 可以⽤来防⽌头⽂件重复引⽤

#ifndef HEADER1_H   //if not defined 条件编译 检查当前头文件是否已经被引用过了
#define HEADER1_H   //如果没有被引用过,则定义一个名为指定名称的宏
程序段1 //如果没有被引用过,编译程序段1,程序段1一般就是HEADER1_H的主体内容
#else
程序段2// 如果被引用过,忽略程序段1
#endif

条件指示符#ifndef的最主要目的是防止头文件的重复包含和编译。条件编译当然也可以用条件语句来实现, 但是用条件语句将会对整个源程序进行编译,生成的目标代码程序很长,而采用条件编译,则根据条件只编译其中的程序段1或程序段2,生成的目标程序较短。

3.define不分配内存,给出的是⽴即数,有多少次使⽤就进⾏多少次替换

立即数指的是在程序执行过程中直接出现的常量值,而不是存储在内存中的变量,比如上面的例子中PI直接被替换成数值,而不是像我们平时那样定义一个变量double PI = 3.14159

4.在编译的预处理阶段起作用,也就是在编译代码之前进行的处理,将所有的宏定义进行替换

typedef

1.用于创建新的数据类型别名。它的语法如下:

typedef 原类型 新类型名;

例如:

typedef unsigned int uint;

这样,uint 就是 unsigned int 的别名,可以在程序中使用 uint 代替 unsigned int

因为它的作用是定义一个新的名称来表示一个已有的数据类型。如果定义的名称已经存在或者没有对应的数据类型,就会导致编译错误。因此在使用typedef之前需要对已有的数据类型进行判断。

2. 在静态存储区中分配空间,在程序运⾏过程中内存中只有⼀个拷⻉

内存中的拷贝通常是指一个数据在内存中有多个副本,也就是有多个变量名指向同一个内存地址。这种情况在程序中比较常见,例如在函数调用时传递参数,会将参数的值复制一份到函数内部的堆栈中。在这种情况下,原始变量和复制变量在内存中的位置不同,但它们的值相同。

typedef unsigned int uint;
uint a = 1;
uint b = a;
uint c = a;

 这个别名在程序中的使用和原始类型是一样的,只是为了让程序员更方便地使用。当程序中使用my_int类型时,编译器会将其解释为int类型,因此只会有一个int类型的内存副本,而不是多个拷贝。

3. 是在编译、运⾏的时候起作⽤

inline 内联

inline int max(int a, int b) {
    return a > b ? a : b;
}

int main() {
    int x = 10, y = 20;
    int z = max(x, y);  // 调用 max 函数
    return 0;
}

提示编译器将函数内容直接嵌入调用它的地方,而不是像普通函数一样进行函数调用。

  • 可以提高程序的执行效率,因为函数调用时需要保存现场、压栈、跳转等操作,而这些操作在函数嵌入时可以省略。
  • 内联函数是⼀种特殊的函数,会进⾏类型检查
  • 不能存在任何形式的循环语句
  • 不能存在过多的条件判断语句
  • 内联函数声明必须在调⽤语句之前

http://www.kler.cn/a/2235.html

相关文章:

  • 国家网络安全法律法规
  • Cyberchef配合Wireshark提取并解析HTTP/TLS流量数据包中的文件
  • JVM 中的完整 GC 流程
  • 【121. 买卖股票的最佳时机】——贪心算法/动态规划
  • JSON-RPC-CXX深度解析:C++中的远程调用利器
  • HTML之表单学习记录
  • nginx 快速入门
  • IDEA一键构建Docker镜像
  • WPF UpdateSourceTrigger属性
  • 这一次,吃了Redis的亏,也败给了GPT
  • 冒泡 VS 插入 VS 选择——谁更胜一筹?(附排序源码)
  • 【iOS】—— ARC学习
  • 学习前端day01
  • 【百面成神】Redis基础11问,你能坚持到第几问
  • 瑞萨Renesas RA2L1 开发板测评(2)--LED闪烁
  • web前端框架——Vue的特性
  • Python程序员看见一个好看的手机壁纸网站,开撸!
  • Linux操作系统ARM体系结构处理器机制原理与实现
  • Vue面试题 路由守卫
  • 【Hive】HQL
  • 【2023新星计划 】博客创作指导 活动解读
  • ChatGPT应用场景与工具推荐
  • GPT-4是个编程高手,真服了!
  • MyBatis --- 缓存、逆向工程、分页插件
  • 【K8S系列】深入解析Pod对象(一)
  • MySQL-触发器