And*_*ech 213
typedef遵守范围规则就像变量一样,而define
保持有效直到文件结束(或直到匹配undef).
此外,有些事情可以通过无法完成的事情typedef来完成define.
例子:
typedef int* int_p1;
int_p1 a, b, c; // a, b, c are all int pointers
#define int_p2 int*
int_p2 a, b, c; // only the first is a pointer, because int_p2
// is replaced with int*, producing: int* a, b, c
// which should be read as: int *a, b, c
Run Code Online (Sandbox Code Playgroud)
.
typedef int a10[10];
a10 a, b, c; // create three 10-int arrays
Run Code Online (Sandbox Code Playgroud)
.
typedef int (*func_p) (int);
func_p fp; // func_p is a pointer to a function that
// takes an int and returns an int
Run Code Online (Sandbox Code Playgroud)
pmg*_*pmg 110
没有.
#define是一个预处理器令牌:编译器本身永远不会看到它.
typedef是一个编译器令牌:预处理器不关心它.
您可以使用其中一种来达到相同的效果,但最好根据您的需要使用合适的效果
#define MY_TYPE int
typedef int My_Type;
Run Code Online (Sandbox Code Playgroud)
当事情变得"毛茸茸"时,使用正确的工具使其正确
#define FX_TYPE void (*)(int)
typedef void (*stdfx)(int);
void fx_typ(stdfx fx); /* ok */
void fx_def(FX_TYPE fx); /* error */
Run Code Online (Sandbox Code Playgroud)
Joh*_*ode 21
不,他们不一样.例如:
#define INTPTR int*
...
INTPTR a, b;
Run Code Online (Sandbox Code Playgroud)
在预处理之后,该行扩展为
int* a, b;
Run Code Online (Sandbox Code Playgroud)
希望你看到问题; 只会a有类型int *; b将被声明为plain int(因为*它与声明符相关联,而不是类型说明符).
与之形成鲜明对比
typedef int *INTPTR;
...
INTPTR a, b;
Run Code Online (Sandbox Code Playgroud)
在这种情况下,无论是a和b将有类型int *.
有些类型的typedef无法使用预处理器宏进行模拟,例如指向函数或数组的指针:
typedef int (*CALLBACK)(void);
typedef int *(*(*OBNOXIOUSFUNC)(void))[20];
...
CALLBACK aCallbackFunc; // aCallbackFunc is a pointer to a function
// returning int
OBNOXIOUSFUNC anObnoxiousFunc; // anObnoxiousFunc is a pointer to a function
// returning a pointer to a 20-element array
// of pointers to int
Run Code Online (Sandbox Code Playgroud)
尝试使用预处理器宏执行此操作.
预处理器宏(" #defines")是词法替换工具,"搜索和替换".他们完全不了解编程语言,也不了解你想要做什么.您可以将它们视为美化的复制/粘贴机制 - 偶尔会有用,但您应该小心使用它.
Typedef是一种C语言功能,允许您为类型创建别名.这对于使复杂的复合类型(如结构和函数指针)可读和可处理非常有用(在C++中甚至有必须键入一个类型的情况).
对于(3):在可能的情况下,您应该总是喜欢语言功能而不是预处理器宏!所以总是对类型使用typedef,对常量使用常量值.这样,编译器实际上可以与您进行有意义的交互.请记住编译器是你的朋友,所以你应该尽可能地告诉它.预处理器宏通过隐藏编译器中的语义来完全相反.