Typedef 和 # 的定义在 c 中是否相同?

我想知道 中的 typedef#define是否相同?

76022 次浏览

没有。

#define是一个预处理令牌: 编译器本身将永远不会看到它。
typedef是一个编译器令牌: 预处理器不关心它。

您可以使用其中一种方法来达到同样的效果,但最好是根据您的需要使用适当的方法

#define MY_TYPE int
typedef int My_Type;

当事情变得“棘手”的时候,使用适当的工具可以使它变得正确

#define FX_TYPE void (*)(int)
typedef void (*stdfx)(int);


void fx_typ(stdfx fx); /* ok */
void fx_def(FX_TYPE fx); /* error */

AFAIK,不。

typedef可以帮助您为现有的数据类型建立一个“别名”

#define是一个 预处理器指令,用于定义宏或一般模式替换。为了..。#define MAX 100,用100代替 MAX的所有出现

没有。
Typedef是为类型创建别名的 C 关键字。释义是一个预处理器指令,它在编译之前创建一个文本替换事件。当编译器到达代码时,原来的“ # 定义”字不再存在。# Definition 主要用于宏和全局常量。

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
typedef int a10[10];
a10 a, b, c;  // create three 10-int arrays
typedef int (*func_p) (int);
func_p fp;  // func_p is a pointer to a function that
// takes an int and returns an int

不,它们不一样,例如:

#define INTPTR int*
...
INTPTR a, b;

预处理后,该行扩展为

int* a, b;

希望您能够看到这个问题; 只有 a具有 int *类型; b将被声明为纯 int(因为 *与声明器相关联,而不是与类型说明符相关联)。

对比一下

typedef int *INTPTR;
...
INTPTR a, b;

在这种情况下,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

试着用一个预处理器宏来做这件事。

它们是非常不同的,尽管它们通常用于实现自定义数据类型(这就是我假设这个问题的所有内容)。

正如 pmg 所提到的,在编译器看到代码之前,#define由预处理器处理(像剪切和粘贴操作一样) ,而 typedef由编译器解释。

主要的区别之一(至少在定义数据类型时)是 typedef允许更具体的类型检查。比如说,

#define defType int
typedef int tdType


defType x;
tdType y;

在这里,编译器将变量 x 视为 int,而将变量 y 视为名为“ tdType”的数据类型,其大小恰好与 int 相同。如果您编写的函数采用 defType 类型的参数,那么调用方可以传递一个普通的 int,而编译器不会知道其中的差异。如果函数采用 tdType 类型的参数,编译器将确保在函数调用期间使用适当类型的变量。

另外,一些调试器具有处理 typedef的能力,这比将所有自定义类型列为其基础原语类型(如果使用 #define就会这样)要有用得多。

预处理器宏(“ #define”)是一种词法替代工具,就像“搜索和替换”一样。他们完全不了解编程语言,不知道您要做什么。您可以将它们看作是一个美其名曰的复制/粘贴机制——有时候这是有用的,但是您应该谨慎使用它。

Typedefs 是一个 C 语言特性,它允许您为类型创建别名。这对于使复杂的复合类型(如结构和函数指针)具有可读性和可处理性非常有用(在 C + + 中,甚至有些情况下 必须的 typedef 是一种类型)。

在可能的情况下,您应该总是更喜欢语言特性而不是预处理器宏!因此,类型始终使用 typedef,常量使用常量值。这样,编译器实际上可以与您进行有意义的交互。请记住,编译器是你的朋友,所以你应该告诉它尽可能多。预处理器宏通过编译器中的 躲起来完全执行相反的语义。

# Definition 定义宏。
Typedef 定义类型。

现在说到这里,有一些不同之处:

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

Typedef 可用于为类型提供别名(您可能也可以使用 # 定义) ,但是由于 # 定义常量的查找和替换特性,所以它更安全。
除此之外,您可以使用 译自: 美国《每日邮报》网站(http://en.wikipedia.org/wiki/Forward _ Declaration)前向声明:Typedef,它允许您声明将要使用的类型,但是还没有链接到您正在编写的文件。

正如上面所说的,它们是不一样的。大多数的答案表明 typedef#define更有优势。 但是让我加上 #define的一个优点: < br > 当你的代码非常大,分散在很多文件中时,最好使用 #define; 它有助于提高可读性——你可以简单地预处理所有的代码,在变量声明本身的地方查看它的实际类型定义。译注:

如上所述,#define和 typedef 之间有一个关键的区别。考虑这个问题的正确方法是将 typedef 视为一个完整的“封装”类型。它意味着在声明它之后不能对它进行添加。

可以使用其他类型说明符扩展宏类型名,但不能使用 typedef’d 类型名:

#define fruit int
unsigned fruit i;   // works fine


typedef int fruit;
unsigned fruit i;   // illegal

另外,typedef’d 名称为声明中的每个声明程序提供类型。

#define fruit int *
fruit apple, banana;

宏观扩张之后,第二行是:

int *apple, banana;

Apple 是一个指向 int 的指针,而 banana 是一个 int。相比之下,typedef 是这样的:

typedef char *fruit;
fruit apple, banana;

宣称苹果和香蕉是一样的。前面的名称不同,但它们都是指向 char 的指针。

使用 typedef 的另一个原因(在其他答案中只简要提到过,但我认为这是创建 typedef 的全部原因)是为了在使用具有自定义类型的库时更容易进行调试。例如,我将使用类型转换错误。下面的两个代码都会打印一个编译时错误,说明 char 不能与字符串相比,而是以不同的方式。

typedef char letter;
letter el = 'e';
if(el == "hello");

上面的代码将打印类似 the variable "el" of type letter (aka "char") is not compatable with type "char*"的内容

#define letter char
letter el = 'e';
if(el == "hello");

此代码将改为打印 the variable "el" of type char is not compatable with type "char*"

这可能看起来很傻,因为我将“字母”定义为“ char”,但是在更复杂的库中,这可能会非常令人困惑,因为指向诸如按钮、窗口、声音服务器、图像等对象的指针都被定义为 unsigned char *,当使用 # Definition 方法时,它只能被调试为完全可调试的 unsigned char *