C 想知道一些技巧吗

C 想知道一些技巧吗,c,c-preprocessor,C,C Preprocessor,在阅读我小组项目的代码时,我遇到了许多定义,其中一些似乎很奇怪。为了概括它,请看下面的两个例子 例1: #define SNPRINTF(dst, fmt, arg...) snprintf(dst, sizeof(dst), fmt, ##arg) 在这种情况下意味着什么?我试着删除它们,并编写类似char buf[1024]的代码;SNPRINTFbuf,%s,%s,abcd,efg;这产生了同样的结果。看来对我没有用也没有伤害 例2: #define CLOSE(fd) do {

在阅读我小组项目的代码时,我遇到了许多定义,其中一些似乎很奇怪。为了概括它,请看下面的两个例子

例1:

#define SNPRINTF(dst, fmt, arg...)  snprintf(dst, sizeof(dst), fmt, ##arg)
在这种情况下意味着什么?我试着删除它们,并编写类似char buf[1024]的代码;SNPRINTFbuf,%s,%s,abcd,efg;这产生了同样的结果。看来对我没有用也没有伤害

例2:

#define CLOSE(fd)   do  {   \
        if (-1 != (fd)) {   \
                    close(fd);  \
                    (fd)    = -1;   \
                }   \
} while (0)
是否需要将内部代码填充到do{}while0语句中?有什么用

。。。根据C99标准确定一个新的标准。根据标准,表示右侧所有剩余参数扩展的标记是uu VA_ARGS_uuu-我想您正在使用的一些C编译器带有非标准扩展,允许您使用的不同形式是预处理器标记粘贴操作符,但我不知道这在这里是如何应用的

第二种形式是一种比C89更古老的经典技巧,以确保;在宏行为正确后,在它没有绑定到错误的if之后使用else,依此类推。基本上,包装该操作所需的多个语句和条件语句…同时将它们安全地嵌套在一个块中,该块之后需要一个分号,语法上就像宏调用是一个函数调用一样。

。。。根据C99标准确定一个新的标准。根据标准,表示右侧所有剩余参数扩展的标记是uu VA_ARGS_uuu-我想您正在使用的一些C编译器带有非标准扩展,允许您使用的不同形式是预处理器标记粘贴操作符,但我不知道这在这里是如何应用的


第二种形式是一种比C89更古老的经典技巧,以确保;在宏行为正确后,在它没有绑定到错误的if之后使用else,依此类推。基本上,包装该do中所需的多个和条件语句……同时将它们安全地嵌套在一个块中,该块之后需要一个分号,语法上就像宏调用是一个函数调用一样。

两个按顺序回答您的问题:

是粘贴操作符,因此它实际上不做任何事情。我想找不到任何引用,它有非标准版本,如果前面的逗号是空的,它会吃掉它,所以这可能就是它的用途。 如前所述,do{…}while0是一个标准技巧,用于确保粘贴到。。。可以作为单个语句处理。它通常允许您编写以下内容:
不用担心。

两个问题按顺序回答:

是粘贴操作符,因此它实际上不做任何事情。我想找不到任何引用,它有非标准版本,如果前面的逗号是空的,它会吃掉它,所以这可能就是它的用途。 如前所述,do{…}while0是一个标准技巧,用于确保粘贴到。。。可以作为单个语句处理。它通常允许您编写以下内容:
不用担心。

这个问题以前已经回答过了。我将尝试挖掘一个链接。只找到问题的一部分:这个答案:讨论了do while问题,但我知道还有一个问题是单独的问题。他们在这儿:也许吧others@dmckee感谢有价值的链接!你是怎么挖的?仅仅凭记忆,或者网站除了标签之外还提供了一些有用的工具?这里描述了一些搜索操作人员,但大部分情况下我都是在搜索结果页面中搜索的。当你知道答案在那里的时候,你会更容易接受。这个问题以前已经被回答过了。我将尝试挖掘一个链接。只找到问题的一部分:这个答案:讨论了do while问题,但我知道还有一个问题是单独的问题。他们在这儿:也许吧others@dmckee感谢有价值的链接!你是怎么挖的?仅仅凭记忆,或者网站除了标签之外还提供了一些有用的工具?这里描述了一些搜索操作人员,但大部分情况下我都是在搜索结果页面中搜索的。当你知道答案在那里时,你会更容易接受。。。和args组合是一个GCC预处理器扩展,请参阅args。。。和args组合是一个GCC预处理器扩展,请参见
if( floon )
  CLOSE(floon);