我在学习C语言中的函数和类似函数的宏.

我读了C标准,发现了这个:

函数的任何宏定义都可以通过将函数的名称括在圆括号中来局部取消,因为该名称后面没有表示宏函数名展开的左括号.出于相同的语法原因,允许使用库函数的地址,即使它也被定义为宏.185)使用#undef删除任何宏定义也将确保引用实际的函数.

因此,根据这一点,如果我想确保GET将是我代码中的一个函数,我必须访问<stdio.h>头文件,并将(我不知道是函数名还是宏名)括在括号或#undef宏中?

我的意思是:int (getc)(FILE *stream);(或者这个?#define (getc)(...) ) 或者这样: 一百零二

但这一切都在<stdio.h>档案?

还是在我的代码里?

你能给我一个例子,说明如何确保在C中使用getc作为函数吗?

推荐答案

正如引用的段落中所解释的,有一种简单的方法可以防止标准库头中定义的类似函数的宏的宏扩展:使用后面不跟(的标识符来引入参数列表,例如:在标识符两边使用括号.

例如:

#include <stdio.h>

// copy stdin to stdout bypassing macro expansion
int main(void) {
    int c;
    while ((c = (getc)(stdin)) != EOF) {
        (putc)(c, stdout);
    }
    return 0;
}

或者,您可以在使用代码中的函数之前取消定义宏.这将确保预处理器保持getcputc标识符不变,并且编译器将使用它们在<stdio.h>中的函数声明.

#include <stdio.h>

// copy stdin to stdout preventing macro expansion

#undef getc
#undef putc
#undef fgetc
#undef fputc

int main(void) {
    int c;
    while ((c = getc(stdin)) != EOF) {
        putc(c, stdout);
    }
    return 0;
}

一种更简单的方法是使用函数fgetcfputc,即使它们也可以被实现为用于性能的宏,它们也被保证表现为函数:

#include <stdio.h>

// copy stdin to stdout using the functions
int main(void) {
    int c;
    while ((c = fgetc(stdin)) != EOF) {
        fputc(c, stdout);
    }
    return 0;
}

在任何情况下,都不要try 修改标准标头,因为在现代系统上,标头应该是只读的.

另请注意,在<stdio.h>中定义的标准函数的宏版本只允许对流参数(对应于FILE *的参数)进行多次求值,而不允许对字符参数进行多重求值.不能保证这一点的古代系统不符合任何C标准,并且完全过时.例如,参见ISO C90文件中putc函数的规范:

7.9.7.8 100 function

Synopsis

#include <stdio.h>
int putc(int c, FILE *stream);

Description

putc函数等同于fputc,不同之处在于,如果它作为宏实现,它可能会多次计算stream,因此参数永远不应该是有副作用的表达式.

最后一句话是:不要担心这一点,毫不犹豫地使用宏或函数,但不要将有副作用的表达式作为流参数传递,这无论如何都会非常麻烦和容易出错.

C++相关问答推荐

初始化char数组-用于初始化数组的字符串是否除了存储数组的位置之外单独存储在内存中

有什么方法可以检测SunOS上的SparcWorks吗?

为什么PLT表中没有push指令?

无效使用未定义类型'structsquare'?

常数函数指针优化

编译SDL 2时缺少SDL_ttf

VS代码C/C++扩展intellisense无法检测环境特定函数'

C语言中字符数组声明中的标准

理解C版宏(看起来像未声明的变量?)

为什么中断函数会以这种方式影响数组?

处理EPOLL_WAIT中的接收数据和连接关闭信号

如何使用唯一数字对整型进行分区

我在C中运行和调试时得到了不同的输出

将 struct 数组写入二进制文件时发生Valgrind错误

*S=0;正在优化中.可能是GCC 13号虫?或者是一些不明确的行为?

访问未对齐联合的成员是否为未定义行为,即使被访问的成员已充分对齐?

Ubuntu编译:C中的文件格式无法识别错误

使用 _Atomic float 时,MSVC 编译的代码会命中调试断言

如何修复数组数据与列标题未对齐的问题?

使用邻接表创建图