C++排雷:22.#define和typedef的区别

    技术2023-12-16  116

    #define 和typedef都是起别名,增强了代码的可读性。但它们有所不同:

    1.原理不同2.功能不同3.执行时间不同4.作用域不同5.对指针的操作不同typedef 的几点注意:

    1.原理不同

    #define是C语言中定义的语法,是预处理指令,在预处理时进行简单而机械的字符串替换,不作正确性检查,只有在编译已被展开的源程序时才会发现可能的错误并报错。typedef是关键字,在编译时处理,有类型检查功能。它在自己的作用域内给一个已经存在的类型一个别名,但不能在一个函数定义里面使用typedef。用typedef定义数组、指针、结构等类型会带来很大的方便,不仅使程序书写简单,也使意义明确,增强可读性。

    2.功能不同

    typedef用来定义类型的别名,起到类型易于记忆的功能。另一个功能是定义机器无关的类型。#define不只是可以为类型取别名,还可以定义常量、变量、编译开关等,通俗讲就是啥都能起外号,机械的替换罢了。

    3.执行时间不同

    #define 是在预处理阶段,也就是在编译之前typedef是在编译阶段

    4.作用域不同

    #define是预处理,无论在哪定义的,在整个文件都能用。typedef只能在定义的作用域内使用。

    5.对指针的操作不同

    直接上例子:

    typedef int * pint; #define PINT int * int i1 = 1, i2 = 2; const pint p1 = &i1; //p不可更改,p指向的内容可以更改,相当于 int * const p; const PINT p2 = &i2; //p可以更改,p指向的内容不能更改,相当于 const int *p;或 int const *p; pint s1, s2; //s1和s2都是int型指针 PINT s3, s4; //相当于int * s3,s4;只有一个是指针。 void TestPointer() { cout << "p1:" << p1 << " *p1:" << *p1 << endl; //p1 = &i2; //error C3892: 'p1' : you cannot assign to a variable that is const *p1 = 5; cout << "p1:" << p1 << " *p1:" << *p1 << endl; cout << "p2:" << p2 << " *p2:" << *p2 << endl; //*p2 = 10; //error C3892: 'p2' : you cannot assign to a variable that is const p2 = &i1; cout << "p2:" << p2 << " *p2:" << *p2 << endl; }

    结果:

    p1:00EFD094 *p1:1 p1:00EFD094 *p1:5 p2:00EFD098 *p2:2 p2:00EFD094 *p2:5

    typedef 的几点注意:

    typedef 可以声明各种类型名,但不能用来定义变量。用 typedef 可以声明数组类型、字符串类型,使用比较方便。用typedef只是对已经存在的类型增加一个类型名,而没有创造新的类型。当在不同源文件中用到同一类型数据(尤其是像数组、指针、结构体、共用体等类型数据)时,常用 typedef声明一些数据类型,把它们单独放在一个头文件中,然后在需要用到它们的文件中用 #include 命令把它们包含进来,以提高编程效率。使用 typedef 有利于程序的通用与移植。有时程序会依赖于硬件特性,用 typedef 定义与平台无关的类型便于移植。

    比如,定义一个叫 FALSE 的浮点类型,在目标平台一上,让它表示最高精度的类型为: typedef long double FALSE; 在不支持 long double 的平台二上,改为: typedef double FALSE; 在连 double 都不支持的平台三上,改为: typedef float FALSE;

    也就是说,当跨平台时,只要改下 typedef 本身就行,不用对其他源码做任何修改。

    标准库就广泛使用了这个技巧,比如 size_t。

    参考文献1 参考文献2 参考文献3

    Processed: 0.013, SQL: 9