个人预处理器指令

时间:2009-08-01 09:00:04

标签: c macros c-preprocessor

作为 C 新手,我想听听Macro“定义”开发人员正在使用的内容。我一直在考虑把它们放在一个标题中,以省略我已经习惯的冗长:

#define TS_ typedef struct {  
#define _TS(x) } x;

#define I(x)_ { int i; for ( i = 1; i <= x; i++ ) {  
#define _I } }

我可以在这些宏中添加\ n \ t等吗?因为我想传递我的源代码减去额外的包括:

#define TS_ typedef struct {\n
#define _TS(x) } x;\n

#define I(x)_ { int i;\n\tfor ( i = 1; i <= x; i++ ) {\n 
#define _I \t}\n}\n

这些会有用吗?

ie:我可以使用预处理器将我的源代码替换为我的个人包含格式化源代码而不包含吗?

良好的预处理器提示和技巧的链接也很受欢迎。

9 个答案:

答案 0 :(得分:16)

在开始之前,不要使用以下划线开头的宏名称 - 这些是为编译器和标准库编写者保留的,不得在您自己的代码中使用。

另外,我会说你建议的宏都是非常糟糕的想法,因为它们会向读者隐瞒正在发生的事情。他们唯一的理由似乎是为您节省很少的打字。通常,只有在没有明智选择的情况下才应该使用宏。在这种情况下有一个 - 只需编写代码。

答案 1 :(得分:6)

可以通过转义换行符

放入空格
#define SOMETHING whatever\
This is part of the macro

但正如其他人所说,这并不是一个很好的方法。

查看编辑器宏会更好,因此您可以键入快捷方式并让编辑器展开它。

答案 2 :(得分:4)

你走向了错误的道路。 不要制作自己不熟悉的cpp指令 - 这会使您的代码难以理解,并且在某些时候维护。

尝试找一些好的C代码来阅读 - 好的C代码不会使用这些东西,这是有充分理由的。

答案 3 :(得分:3)

不要做。其他任何人都无法阅读您的代码。

作为一个警示示例,请查看Steve Bourne's original sources for the Bourne shell,在那里他使用宏以一种pidgin Algol风格编写代码。

答案 4 :(得分:1)

可以这样做,但这种“个人语言”通常不会在C世界中使用,特别是如果你希望其他人在将来阅读你的代码。

如果你只为自己做这件事,那么随意#define你想要什么,但是一旦你开始和其他人一起工作,你就无法继续使用这种事情。

答案 5 :(得分:1)

不必要地使用C宏可能会让您陷入痛苦的世界,特别是如果您尝试使用它来扩展代码。 C宏有用,但不是这样。

编辑:我意识到我的答案与你的问题相关,但我想我应该提一下,因为你说你是C新手。搜索“C宏陷阱”以获取不使用宏的原因的完整列表。之前已经讨论过here

答案 6 :(得分:0)

一般情况下,我非常同意其他受访者,他们告诉您不要仅仅为了节省打字而定义自己的宏。混淆是不值得的。此外,您建议的特定宏是令人发指的。然而,在Stroustrup的第一版中,他做了我喜欢的事情(有时候):

#define Kase break; case

答案 7 :(得分:0)

我已经习惯了Python elif构造,所以我经常定义以下内容:

#define elif(test) else if(test)

我这样做的目的不是来减少输入,而是在保持一致的代码宽度的同时保持缩进逻辑(我不会让我的代码超过80个字符)。我这样说是因为我...

if(...) ...
else if(...) ...
else ...

......应该......

if(...)
{
    ...
}

else
    if(...)
    {
        ...
    }

    else
    {
        ...
    }

用我的宏变成:

if(...)
{
    ...
}

elif(...)
{
    ...
}

else
{
    ...
}

答案 8 :(得分:0)

将循环变量传递给宏总是更好。 块 - 宏具有某些优化问题。所有编译器都不保证“块范围”变量的优化obj代码。

例如,以下代码在编译时没有为gcc提供任何优化选项时,会为&amp; i打印两个单独的地址。使用-O2选项编译时,相同的代码将在两个块中打印相同的地址。

{
    int i;
    printf("address of i in first block is %u\n", &i);
}
{
    int i;
    printf("address of i in sec block is %u\n", &i);
}

适当地命名语言结构使代码更具可读性。 如果按照以下方式表达,我喜欢你的想法。

#define GREEN 1
#define YELLOW 2
#define RED 3

# define NUM_COLORS 3

#define COLOR_ITER (color,i)           \
    for(i=GREEN, color = colors[i];    \
        i < NUM_COLORS;                \
        color = colors[++i])

int colors[3] = {GREEN, YELLOW, RED};

int
fun () {

    int j;
    color_t clr;

    COLOR_ITER(clr, j) {
        paint(clr);
    }

}

在这里,无论它是如何编写的,宏名称COLOR_ITER的名称都暗示着你为所有可用的颜色循环并为每种颜色做“某事”。这是一个非常易于使用的宏。

你的问题

  

我可以使用预处理器将我的源代码替换为我的个人包含格式化源代码而不包含吗?

正如大家所解释的那样,预处理器在这种情况下无法帮助你。 您可以使用编辑器命令在键入代码时自动格式化代码。