[英]Is it possible to typedef a preprocessor directive?
最近我开始学习C,我读过关于typedef
,我知道typedef
是现有类型的别名。
因此可以typedef
一个预处理器指令吗? 例如,
typedef #include I;
能够以后做
I <stdio.h>
代替
#include <stdio.h>
您几乎自己回答了这个问题: typedef
用于别名现有类型 。 它不是粗略的文本替代机制。 (Pithily说,一个用途就是它可以使你不必在整个地方编写struct
:参见typedef struct vs struct definitions )
但像#include
这样的预处理程序指令 不是一种类型,因此它不能以您想要的方式使用。
另请注意,对于每个转换单元 ,预处理阶段在任何编译开始之前完成。 您的想法看起来依赖于编译器与预处理器的交互。 语言没有这样设置。
最后要注意的是, typedef
机制在C和C ++中有很大的不同。 在C中,所有typedefs
都被注入一个单独的命名空间 。 请参阅了解C命名空间 。 这都是非常复杂的东西,我在这里引入了相当数量的术语,我将它用于斜体 。 首先要掌握基础知识。
不。 正如其他人所指出的那样,预处理器在编译之前运行,并且可能对该行没有做任何特殊处理(因为它不是以#
开头,尽管你可以使用#define
来改变它)。
此外,您不能将宏用于预处理器指令。 如果可以,你可以写#define I #include
,但你不能,不会工作。 即使你可以,你绝对不应该(除非你正在写一些有意混淆的代码或做源代码布局艺术或其他什么),这几乎被认为是任何人的坏代码。
如果您确实想要实现某些目标(而不仅仅是好奇或想要保存打字),您可以询问您的实际问题。
正如我评论的那样,你应该努力让你的C代码可以被其他人读取 (包括你自己在6个月后)。 因此,使用I <stdio.h>
的替代#include <stdio.h>
确实是一个坏主意(因为你I
要少得多可读)。
因此可以键入一个预处理器指令吗?
不 ,这是不可能的......
但是,请记住,您始终可以通过其他方式(来自其他来源) 生成 C代码。 在你的情况下,我认为这在实践中是一个坏主意,但你可能会考虑使用其他一些预处理器 - 也许是GPP或m4 - (或某些脚本,甚至可能是一个简单的awk )从例如生成你的foo.c
文件一些foo.mahendra
one; 那么你将相应地修改你的构建过程(如果你使用GNU make进行构建自动化 ,你只需要添加一个依赖项和规则)。
阅读有关C预处理器的信息 。 今天,它通常是编译器的一部分。 在上个世纪,它是一个单独的程序/lib/cpp
。 阅读GNU cpp的文档。 阅读更多关于C11的信息 ,例如(草案)标准n1570 ,以及一些像这样的网站。
顺便说一句,有时值得研究预处理器的结果。 给定一些文件foo.c
你可能会运行(假设GCC是你的编译器) gcc -C -E foo.c > foo.i
(可能还有其他预处理选项 ,比如-I/usr/local/include
,就在gcc
之后)进入foo.i
foo.c
的预处理形式。 预处理的foo.i
文件是一个文本文件,您可以使用某个编辑器或寻呼机进行检查。
无法使用typedef为预处理程序指令设置别名。 typedef
是一个关键字,由编译器处理,而不是预处理器。 预处理器从代码中删除注释,并用适当的输出替换预处理器指令,如#include
。 编译ac程序时,实际上会发生三件事:
#include
。 因此,尽管您不能使用typedef来为预处理程序指令设置别名,但您可以(尽管您可能不应该)执行以下操作:
uselessTypedef.h
int NUMBER
uselessTypedef.c
#include <stdio.h>
// note the whitespace between the typedef, #include and the semicolon
// typedef #include "uselessTypedef.h"; doesn't compile because of the way the preprocessor and compiler handle things
typedef
#include "uselessTypedef.h"
;
NUMBER main(NUMBER argc, char* argv[])
{
NUMBER myint = 12345;
printf("value of NUMBER myint: %d\n", myint);
return 0;
}
此代码编译并打印value of NUMBER myint: %d\\n
编译器永远不会看到以下代码:
typedef
#include "uselessTypedef.h"
;
相反,编译器看到这个:
typedef
int NUMBER
;
编译器忽略空格,因此代码与typedef int NUMBER;
( #include
)是一个预处理器宏,是“包含外部文件”的词法替换工具。 预处理器是不可知的语言,没有理解和你想要做什么。
另一方面, typedef
是一种允许您为类型创建自己的别名的功能。 尽管名称不同,但typedef
并未定义新类型; 它只是为现有类型创建一个新名称。 例如,给定:
typedef int my_int;
my_int
是int
的新名称; my_int
和int
是完全相同的类型。 同样,给定上面的struct
定义,您可以编写:
typedef struct foo foo;
该类型已经有一个名称struct foo
。 typedef
声明为同一类型提供了一个新名称foo
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.