C语言中的函数定义

时间:2018-06-11 11:06:34

标签: c macros

此代码抛出错误,表示"代码未查询。"

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

然而,这段代码运行顺利。

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

输出:

C program

此代码也可顺利运行。

#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;
}

输出:

C is life

在第一段代码中,为什么代码不像main那样工作?我不知道串联之后的过程是什么&#39; main&#39;由宏完成。请简单地解释这些代码背后的过程。提前致谢。

我也试过定义代码函数。

#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 program

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

4 个答案:

答案 0 :(得分:0)

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

int code (void);

函数main在汇编代码中声明,这就是你的第二个版本编译正确运行的原因。

如果你想避免这个错误,请添加-Wmissing-prototypes编译标志,以便编译器检查你的函数是否有原型。

答案 1 :(得分:0)

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

code()之前移动main()

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

或转发声明code()

#include<stdio.h>
#define MAIN() c##o##d##e

int code();

int main()
{
    MAIN();
    printf("C program");
    return 0;
}
int code()
{
    printf("C is life");
}

答案 2 :(得分:0)

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

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

// Declare the function, also known as a function prototype
void code(void);

int main(void)
{
    // ...
}

// Define the function
void code(void)
{
    // ...
}

第二个示例有效,因为您使用已在此时声明的main。如果之前未声明函数,则该定义还会声明函数。

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

答案 3 :(得分:0)

请记住macrospreprocessor阶段取代C。在arguments中,每个函数都需要在使用/调用之前进行原型化,以便编译器事先知道它是return typeMAIN()以避免冲突。

案例1: - 当执行以下代码块时,宏名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");
}

预处理器阶段

后面看起来如下
code;

观察上面代码块中的行gcc -Wall -Wstrict-prototypes -Werror test.c,它会导致编译错误。当您在warning之上运行代码时,会将error转换为code()

  

错误:'code'未声明(首次在此函数中使用)#define MAIN()   码                   ^

要解决此问题,请在#define

之前声明int code(void); /* declaration */
code;

还有一个警告转换为错误

  

错误:无效的语句[-Werror = unused-value] #define MAIN()   Ç##ø## d ##ë

因为在宏替换之后它看起来像MAIN()并且编译器正确地抱怨语句上面没有效果。所以要避免这种情况 将宏名称从MAIN更改为#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;
}

更正案例1代码的版本

C is lifeC program

它产生输出

MAIN()

案例2: - 当代码执行时,宏名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");
}

它看起来像是在预处理器阶段

MAIN()

案例3: - 当执行以下代码块时,宏名code已被code()替换为&amp;在这里你也声明了#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

建议您使用

编译任何C代码
date_helper's

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