Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/59.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C语言宏中的函数定义_C_Macros - Fatal编程技术网

C语言宏中的函数定义

C语言宏中的函数定义,c,macros,C,Macros,此代码抛出一个错误,表示“代码未被引用” 这段代码运行也很顺利 #include<stdio.h> #define MAIN() m##a##i##n int main() { MAIN(); printf("C program"); return 0; } int code() { printf("C is life"); } #include <stdio.h> #define macro(n, a, i, m) m##a##i##n

此代码抛出一个错误,表示“代码未被引用”

这段代码运行也很顺利

#include<stdio.h>
#define MAIN() m##a##i##n
int main()
{
    MAIN();
    printf("C program");
    return 0;
}
int code()
{
    printf("C is life");
}
#include <stdio.h>
#define macro(n, a, i, m) m##a##i##n
#define MAIN macro(n, a, i, m)

int MAIN()
{
    printf("C is life");
    return 0;
}
在第一个代码中,为什么代码不像main那样工作?我不知道宏完成连接“main”后的过程是什么。请简单解释这些代码背后的过程。提前谢谢

我还尝试定义代码函数

#include<stdio.h>
#define MAIN() c##o##d##e
int code(void);
int main()
{
    MAIN();
    printf("C program");
    return 0;
}
int code(void)
{
    printf("C is life\n");
    return 0;
}

因此,定义函数不应该是问题所在。我的问题是,连接后会发生什么?提前谢谢

在C中,您必须在任何调用之前定义函数的原型
int code()

int code (void);
函数
main
是在汇编代码中声明的,这就是为什么您的第二个版本可以正确编译et


如果要避免此错误,请添加
-Wmissing prototype
编译标志,以便编译器检查您的函数是否有原型。

问题是编译
main()
时,
code()
函数尚未声明

main()之前移动
code()

在C语言中(自C99标准以来),您需要在使用所有函数之前声明它们

在第一个示例中,您在尝试使用
code
函数之前没有声明它。您可以通过添加函数原型来解决此问题:

第二个示例之所以有效,是因为您使用的是
main
,此时已经声明了它。如果函数以前没有声明过,那么定义也会声明该函数


还请注意,展开后的宏实际上并不调用
code
(或
main
)函数。这很好,因为递归(直接或间接)调用
main
通常是不好的。

请记住
宏在
预处理器
阶段本身被替换。在
C
中,每个函数在使用/调用之前都需要进行原型化,以便编译器提前知道它的
参数
返回类型
,以避免冲突

案例1:-当执行下面的代码块时,宏名
MAIN()
被替换为
code

#define MAIN() c##o##d##e
int main(){
        MAIN();
        printf("C program");
        return 0;
}
int code(){
        printf("C is life");
}
预处理器阶段之后,它如下所示

int main(){
 code; /* errorenous statement */
 printf("C program");
 return 0;
}
int code(){
 printf("C is life");
}
观察行<代码>代码
在上述代码块中,它会导致编译错误。当您运行上面的代码时,如
gcc-Wall-Wstrict prototype-Werror test.c
,它将
警告
转换为
错误

错误:“代码”未声明(首次在此函数中使用)#define MAIN() c#o#d#e ^

要解决此问题,请像前面一样声明
code()
\define

int code(void); /* declaration */
还有一个警告转换为错误

错误:语句无效[-Werror=unused value]#define MAIN() c#o#d#e

因为宏替换后,它看起来像
code这里是上面的语句,没有任何效果。所以为了避免这种情况
将宏名称从
MAIN()
更改为
MAIN
。例如

#define MAIN c##o##d##e
案例1代码的正确版本

#include<stdio.h>
int code(void);
#define MAIN c##o##d##e
int main(void){
        MAIN();
        printf("C program");
        return 0;
}
int code(void){
        printf("C is life");
        return 0;
}
案例2:-当执行下面的代码时,宏名
MAIN()
将替换为
MAIN

#define MAIN() m##a##i##n
int main(){
    MAIN();
    printf("C program");
    return 0;
}
int code(){
    printf("C is life");
}
它看起来像是在预处理器阶段

int main(){
    main; /* it causes error */
    printf("C program");
    return 0;
}
int code(){
    printf("C is life");
}
案例3:-当执行下面的代码块时,宏名
MAIN()
被替换为
code
&这里您也声明了
code()

#define MAIN() c##o##d##e
int code(void);
int main() {
    MAIN();
    printf("C program");
    return 0;
}
int code(void) {
    printf("C is life\n");
    return 0;
}
在预处理器阶段之后,它如下所示

int code(void);
int main() {
 code;/* error causing statement */
 printf("C program");
 return 0;
}
int code(void) {
 printf("C is life\n");
 return 0;
}
建议您使用

gcc -Wall -Wstrict-prototypes -Werror test.c

因此,通过将警告转换为错误,您将了解更多

显然,它应该是
#define MAIN(m,a,i,n)int m#a#i#n();m#a#i#n()
MAIN(c,o,d,e)。根据我需要的澄清,我现在已经很清楚地编辑了这个问题。
MAIN()
在第一种情况下被替换为
code
,而不是
code()
。在第二种情况下,它被替换为
main
,而不是
main()
@Peter我修改了我的答案,以进一步澄清OP问题。请看一看。您可能想解释一下
MAIN()
扩展为
code
,而不是
code()
,因此实际上不调用函数
code()
#define MAIN c##o##d##e
#include<stdio.h>
int code(void);
#define MAIN c##o##d##e
int main(void){
        MAIN();
        printf("C program");
        return 0;
}
int code(void){
        printf("C is life");
        return 0;
}
C is lifeC program
#define MAIN() m##a##i##n
int main(){
    MAIN();
    printf("C program");
    return 0;
}
int code(){
    printf("C is life");
}
int main(){
    main; /* it causes error */
    printf("C program");
    return 0;
}
int code(){
    printf("C is life");
}
#define MAIN() c##o##d##e
int code(void);
int main() {
    MAIN();
    printf("C program");
    return 0;
}
int code(void) {
    printf("C is life\n");
    return 0;
}
int code(void);
int main() {
 code;/* error causing statement */
 printf("C program");
 return 0;
}
int code(void) {
 printf("C is life\n");
 return 0;
}
gcc -Wall -Wstrict-prototypes -Werror test.c