c中的typedef和#define是否相同?

113 c macros typedef c-preprocessor

我不知道是否typedef#define在同一个

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)

  • @Allahjane:扩展变成`void fx_def(void (*)(int) fx);`; 正确的声明是`void fx_def(void (*fx)(int));`。 (3认同)
  • 只有当你准备好放弃语法时,函数指针才能用于宏:`#define FX_TYPE(f)void(*f)(int)`.然后,您将函数声明为:`void fx_def(FX_TYPE(fx));` (3认同)
  • 在typedef`stdfx`之后,该类型的有效对象是指向接收int并且不返回值的函数的指针。 (2认同)

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)

在这种情况下,无论是ab将有类型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)

尝试使用预处理器宏执行此操作.


Yoc*_*mer 12

#define定义宏.
typedef定义类型.

现在说,这里有一些差异:

使用#define,您可以定义可在编译时使用的常量.常量可以与#ifdef一起使用来检查代码的编译方式,并根据编译参数专门化某些代码.
您还可以使用#define声明微型查找和替换宏函数.

typedef可以用来为类型提供别名(你也可以使用#define),但由于#define常量的查找和替换性质,它更安全.
除此之外,您可以使用带有typedef的前向声明,它允许您声明将要使用的类型,但尚未链接到您正在编写的文件.


Ker*_* SB 6

预处理器宏(" #defines")是词法替换工具,"搜索和替换".他们完全不了解编程语言,也不了解你想要做什么.您可以将它们视为美化的复制/粘贴机制 - 偶尔会有用,但您应该小心使用它.

Typedef是一种C语言功能,允许您为类型创建别名.这对于使复杂的复合类型(如结构和函数指针)可读和可处理非常有用(在C++中甚至有必须键入一个类型的情况).

对于(3):在可能的情况下,您应该总是喜欢语言功能而不是预处理器宏!所以总是对类型使用typedef,对常量使用常量值.这样,编译器实际上可以与您进行有意义的交互.请记住编译器是你的朋友,所以你应该尽可能地告诉它.预处理器宏通过隐藏编译器中的语义来完全相反.