繁体   English   中英

是否可以输入预定义指令?

[英]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代码。 在你的情况下,我认为这在实践中是一个坏主意,但你可能会考虑使用其他一些预处理器 - 也许是GPPm4 - (或某些脚本,甚至可能是一个简单的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程序时,实际上会发生三件事:

  1. 首先,预处理器从代码中删除注释,并使用适当的预处理器输出替换相应的预处理器指令,如#include
  2. 然后,编译器获取预处理的代码并将编译的代码输出到目标文件中。
  3. 最后,链接器处理已编译的代码,如果需要,将目标文件合并到一个可执行文件中,并将可执行文件与必要的库链接。

因此,尽管您不能使用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_intint的新名称; my_intint完全相同的类型。 同样,给定上面的struct定义,您可以编写:

typedef struct foo foo;

该类型已经有一个名称struct foo typedef声明为同一类型提供了一个新名称foo

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM