c - C语言预处理器的复杂语法

标签 c stdout stdin stderr

我试图弄清楚 C 中的代码,但我一直在试图理解预处理器部分的实际作用。我不明白的代码部分如下:

#define ERR(source) (perror(source),\
         fprintf(stderr,"%s:%d\n",__FILE__,__LINE__),\
         exit(EXIT_FAILURE))

整个代码很短,如下所示:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define ERR(source) (perror(source),\
             fprintf(stderr,"%s:%d\n",__FILE__,__LINE__),\
             exit(EXIT_FAILURE))

int main(int argc, char** argv) {
    char name[22];
    scanf("%21s",name);
    if(strlen(name)>20) ERR("Name too long");
    printf("Hello %s\n",name);
    return EXIT_SUCCESS;
}

最佳答案

宏中的反斜杠意味着你可以像阅读一行一样阅读下一行,所以归结为:

 #define ERR(source) (perror(source), fprintf(stderr,"s:%d\n",__FILE__,__LINE__), exit(EXIT_FAILURE))

#define 预处理器语句用于用其他代码替换代码,例如

#define SOMECONSTANT 5

将在编译代码之前将代码中的 SOMECONSTANT 替换为 5。预处理器还理解类似函数的语法,这就是您在此处所拥有的。

您的宏产生以下主体:

int main(int argc, char** argv) {
    char name[22];
    scanf("%21s",name);
    if(strlen(name)>20) (perror("Name too long"), fprintf(stderr,"s:%d\n",__FILE__,__LINE__), exit(EXIT_FAILURE));
    printf("Hello %s\n",name);
    return EXIT_SUCCESS;
}

您案例中的宏使用逗号运算符将几条语句放在一起,因此您可以将其作为一条语句使用。通常,您的代码会写成:

int main(int argc, char** argv) {
    char name[22];
    scanf("%21s",name);
    if(strlen(name)>20) {
          perror("Name too long");
          fprintf(stderr,"s:%d\n",__FILE__,__LINE__);
          exit(EXIT_FAILURE);
    }
    printf("Hello %s\n",name);
    return EXIT_SUCCESS;
}

希望你明白现在发生了什么。

关于c - C语言预处理器的复杂语法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40384481/

相关文章:

c fscanf 按模式保存

c - 线程中的信号处理程序

batch-file - Shell.StdOut.ReadAll 返回的垃圾字符

c++ - 如何重定向 stdout 和 stderr 流(多平台)?

python - python 会接受 - (破折号)作为 `open()` 的文件名写入标准输出吗?

javascript - 在 Nodejs 中使用 d8 函数

c - scanf 并且没有执行 switch case

c - "<>"缺失有什么问题

c - 在没有预定义缓冲区的情况下使用 fgets()

c - 在C中,是否可以从getchar的当前缓冲区位置读取字符而不移动缓冲区的指针?