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

时间:2017-02-25 08:40:59

标签: c c-preprocessor typedef

最近我开始学习C,我读过typedef,我知道typedef是现有类型的别名。

因此typedef是否可以使用预处理程序指令?例如,

typedef #include I;

以后可以

I <stdio.h>

而不是

#include <stdio.h>

5 个答案:

答案 0 :(得分:4)

您几乎自己回答:typedef用于对现有的类型进行别名。它不是粗略的文本替代机制。 (Pithily说,一个用途就是让你不必在整个地方写struct:见typedef struct vs struct definitions

预处理程序指令(如#include是一种类型,因此无法以您希望的方式使用它。

另请注意,对于每个转换单元,预处理阶段在任何编译开始之前结束。您的想法看起来依赖于编译器与预处理器的交互。语言没有这样设置。

作为最后一点,请注意typedef机制在C和C ++中有很大不同。在C中,所有typedefs都被注入一个单独的名称空间。见understanding C namespaces。这些都是相当复杂的东西,我在这里引入了相当多的术语,我已经 italicised 。首先要掌握基础知识。

答案 1 :(得分:2)

不。正如其他人所指出的那样,预处理器在编译之前运行,并且可能对该行没有做任何特殊处理(因为它不是以#开头,尽管你可以使用#define来改变它。

此外,您不能将宏用于预处理器指令。如果可以,你可以写#define I #include,但你不能,不会工作。即使你可以,你绝对不应该(除非你正在写一些有意混淆的代码或做源代码布局艺术或其他什么),这几乎被任何人都认为是坏代码。

如果您确实想要实现某些目标(而不仅仅是好奇或想要保存打字),您可以询问您的实际问题。

答案 2 :(得分:2)

正如我评论的那样,您应该努力让其他人(包括您自己在6个月内)自己的C代码可读。因此,使用I <stdio.h>代替#include <stdio.h>实际上是一个坏主意(因为您的I的可读性要低得多)。

  

因此可以输入预处理器指令吗?

这是不可能的......

但是,请记住,您始终可以通过其他方式(来自其他来源)生成 C代码。在你的情况下,我认为这在实践中是一个坏主意,但你可能会考虑使用一些其他预处理器 - 可能GPPm4 - (或某些脚本,也许甚至是简单的awk一个)来生成你的foo.c文件,例如一些foo.mahendra个;那么您将相应地修改您的构建过程(如果您对GNU make使用build automation,那么您只需添加依赖项和规则)。

了解C preprocessor。今天,它通常是编译器的一部分。在上个世纪,它是一个单独的计划/lib/cpp。阅读GNU cpp的文档。另请阅读有关C11的更多信息,例如(草稿)标准n1570,以及this一些网站。

顺便说一句,有时值得研究预处理器的结果。给定一些文件foo.c,您可以运行(假设GCC是您的编译器)gcc -C -E foo.c > foo.i(可能还有-I/usr/local/include,如gcc,就在{{1}之后} {}进入foo.i预处理后的foo.c形式。预处理的foo.i文件是一个文本文件,您可以使用preprocessing optionseditor来检查。

答案 3 :(得分:1)

无法使用typedef为预处理程序指令设置别名。 typedef是一个关键字,由编译器处理,而不是预处理器。预处理器从代码中删除注释,并用适当的输出替换预处理器指令,例如#include。编译c程序时,实际上会发生三件事:

  1. 首先,预处理器从代码中删除注释,并用相应的预处理器输出替换相应的预处理器指令,例如#include
  2. 然后,编译器获取预处理的代码并将编译的代码输出到目标文件中。
  3. 最后,链接器处理已编译的代码,如果需要,将目标文件合并到一个可执行文件中,并将可执行文件与必要的库链接。
  4. 因此,虽然你不能使用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;

    等效

答案 4 :(得分:0)

#include)是一个预处理器宏,是“包含外部文件”的词汇替换工具。预处理器是不可知的语言,不了解你想要做什么。

另一方面,typedef是一项功能,可让您为类型创建自己的别名。尽管有名称,但typedef没有定义新类型;它只是为现有类型创建一个新名称。例如,给定:

typedef int my_int;

my_intint的新名称; my_intint 完全相同的类型。同样,根据上面的struct定义,您可以写:

typedef struct foo foo;

该类型已有名称struct footypedef声明为同一类型指定了新名称foo