C 具有不同参数的函数

C 具有不同参数的函数,c,function,C,Function,我想知道如何定义接收不同类型参数的函数 例如,假设我想定义一个“myprint”函数,该函数接收要打印的字符串和显示第一个字符串背景颜色的整数。(我在控制台中更改颜色没有问题。) 但如果函数只接收第一个字符串,它应该选择背景色作为默认颜色,例如黑色 我认为这个问题可以回答,因为“main”函数有这个功能。它可以不接收参数,或者argc和argv 我是一名初级程序员 编辑: 在Frxstrem的回答之后,我编写了这段代码,其中包含一个void myPrintf(int backgroundColo

我想知道如何定义接收不同类型参数的函数

例如,假设我想定义一个“myprint”函数,该函数接收要打印的字符串和显示第一个字符串背景颜色的整数。(我在控制台中更改颜色没有问题。)

但如果函数只接收第一个字符串,它应该选择背景色作为默认颜色,例如黑色

我认为这个问题可以回答,因为“main”函数有这个功能。它可以不接收参数,或者argc和argv

我是一名初级程序员

编辑:

在Frxstrem的回答之后,我编写了这段代码,其中包含一个
void myPrintf(int backgroundColor,int textColor,char*string)
函数,我希望得到与Frxstrem对两个参数函数的回答相同的结果:

//suppose I have defined colors
#define first(a,...) (a)
#define second(a,b,...) (b)
#define third(a,b,c,...) (c)
#define myprint(...) (myPrintf(first(__VA_ARGS__,BLACK),second(__VA_ARGS__,GRAY),third(__VA_ARGS__)))
void myPrintf(int backgroundColor,int textColor,char * string){
    int color=16*backgroundColor+textColor;
        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),color);
        printf("%s",string);
        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),0x07);
}
int main(){
    myprint(,,"hello");//error
}
但我得到了这个错误:

error C2059: syntax error : ')'

因为您的问题实际上是关于提供默认参数,所以您可以利用可变宏:

// always returns first and second argument, respectively
#define FIRST(a, ...) (a)
#define SECOND(a, b, ...) (b)

// define the color black as a constant
#define BLACK 0x000000

// our C function
void myprint_(const char *string, int bgcolor);

// our C macro
#define myprint(...) (myprint_(FIRST(__VA_ARGS__), SECOND(__VA_ARGS__, BLACK)))

现在
myprint(“你好世界”)
扩展到
myprint(黑色,hello world)
,而
myprint(“hello world”,123456)
扩展到
myprint(黑色,hello world)”
,因为您的问题实际上是关于提供默认参数,所以您可以利用可变宏:

// always returns first and second argument, respectively
#define FIRST(a, ...) (a)
#define SECOND(a, b, ...) (b)

// define the color black as a constant
#define BLACK 0x000000

// our C function
void myprint_(const char *string, int bgcolor);

// our C macro
#define myprint(...) (myprint_(FIRST(__VA_ARGS__), SECOND(__VA_ARGS__, BLACK)))

现在
myprint(“你好世界”)
扩展到
myprint(黑色,hello world)
myprint(黑色,hello world)
扩展到
myprint(黑色,hello world),123456)
,虽然Frxstrem的答案是正确的(他/她有我的投票权),但过于自由地使用预处理器宏是一种代码味道。因此,纯粹主义者的方法是只声明两个函数,其中一个是对另一个函数的简单调用:

void myprint_color(char* string, int color) {
    ...
}

void myprint(char* string) {
    myprint_color(string, kBackgroundColor);
}
这种方法有两个优点:

  • 读者很清楚发生了什么

  • 您不必在单个函数的主体中提供这两个函数的所有功能。即。您可以按如下方式自由实施它:

    void myprint(char* string) {
        ...
    }
    
    void myprint_color(char* string, int color) {
        int savedColor = /* get current text color */;
        /* set the text color */
    
        myprint(string);
    
        /* reset the text color to savedColor */
    }
    
    使用这种方法,简单的函数实际上避免了设置颜色,而另一个函数实际上添加了相关代码,而不是始终设置默认为黑色的颜色

    您可以自由使用更方便实现功能的方法。您可以稍后决定将实现从一种方法更改为另一种方法,而不破坏用户端的代码。一旦提供了默认参数的外观和感觉的预处理器魔术就绪,就不能进行这样的更改


  • 虽然Frxstrem的答案是正确的(他/她对此投了我的赞成票),但过于自由地使用预处理器宏是一种代码味道。因此,纯粹主义者的方法是只声明两个函数,其中一个是对另一个函数的简单调用:

    void myprint_color(char* string, int color) {
        ...
    }
    
    void myprint(char* string) {
        myprint_color(string, kBackgroundColor);
    }
    
    这种方法有两个优点:

  • 读者很清楚发生了什么

  • 您不必在单个函数的主体中提供这两个函数的所有功能。即。您可以按如下方式自由实施它:

    void myprint(char* string) {
        ...
    }
    
    void myprint_color(char* string, int color) {
        int savedColor = /* get current text color */;
        /* set the text color */
    
        myprint(string);
    
        /* reset the text color to savedColor */
    }
    
    使用这种方法,简单的函数实际上避免了设置颜色,而另一个函数实际上添加了相关代码,而不是始终设置默认为黑色的颜色

    您可以自由使用更方便实现功能的方法。您可以稍后决定将实现从一种方法更改为另一种方法,而不破坏用户端的代码。一旦提供了默认参数的外观和感觉的预处理器魔术就绪,就不能进行这样的更改



  • 了解变量函数。您可能希望从这里开始执行此操作:有关函数重载的更多信息,请检查。
    main
    ,它是。
    main
    是一个特例;C在任何其他情况下都不支持函数重载。@阿尔克:我认为这里不需要变量函数。OP只需要参数的默认值(如果未给定)。请阅读有关可变函数的内容。您可能希望从这里开始执行此操作:有关函数重载的更多信息,请检查。
    main
    ,它是。
    main
    是一个特例;C在任何其他情况下都不支持函数重载。@阿尔克:我认为这里不需要变量函数。OP只需要一个未给定的参数的默认值。正如我所说的,我是一个初学者,不太熟悉宏的使用细节。@M.K,据我所知,这是实际执行问题中所问内容的唯一方法,至少在C中是这样。然而,我建议作为一种替代解决方案,只制作两个不同名称的函数(例如,
    myprint
    myprint\u black
    ),并从
    myprint\u black
    中调用
    myprint
    。这不是标准C,可能是gcc扩展?那里的可变宏工作方式不同,
    不跟在名称后面。@JensGustedt事实上,它是一个gcc扩展。我重写了代码,以遵循可变宏的C标准。@Frxstrem,太好了,谢谢。另一个缺点是:以下划线开头的名称保留在文件范围内。因此,您的
    \u myprint
    最好是
    myprint\u
    。正如我所说,我是一名初学者,不太熟悉宏的使用细节。@M.K好吧,据我所知,这是真正实现您在问题中提出的要求的唯一方法,至少是在C中。然而,我建议作为一种替代解决方案,只制作两个不同名称的函数(例如,
    myprint
    myprint\u black
    ),并从
    myprint\u black
    中调用
    myprint
    。这不是标准C,可能是gcc扩展?那里的可变宏工作方式不同,
    不跟在名称后面。@JensGustedt事实上,它是一个gcc扩展。我重写了代码,以遵循可变变量的C标准