简体   繁体   English

具有不同参数的函数

[英]Functions with different arguments

I want to know how can I define a function that receives different type of arguments. 我想知道如何定义一个接收不同类型参数的函数。

For example suppose I want to define a "myprint" function that receives a string to be printed and an integer that shows the background color of the first string.(I have no problems with changing the color in console.) 例如,假设我想定义一个“ myprint”函数,该函数接收要打印的字符串和一个显示第一个字符串的背景色的整数。(在控制台中更改颜色没有问题。)

But if function receives only the first string,it should choose background color as my default,for example black. 但是,如果函数仅接收第一个字符串,则应选择背景颜色作为默认值,例如黑色。

I think this question could be answered because "main" function has this capability.It can receive no arguments,or argc and argv. 我认为可以回答此问题,因为“ main”函数具有此功能。它不能接收任何参数,也不能接收argc和argv。

I am a beginner C programmer. 我是初学者C程序员。

Edit: 编辑:

After Frxstrem's answer,I wrote this code that has a void myPrintf(int backgroundColor,int textColor,char * string) function and I want the same result as Frxstrem's answer for two arg function: Frxstrem的答案之后,我编写了这段代码,该代码具有void myPrintf(int backgroundColor,int textColor,char * string)函数,并且我希望得到与Frxstrem的答案相同两个arg函数的结果:

//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
}

But I get this error: 但是我得到这个错误:

error C2059: syntax error : ')'

Since your question is actually about providing default arguments, you can take advantage of variadic macros: 由于您的问题实际上是关于提供默认参数的,因此您可以利用可变参数宏:

// 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)))

Now myprint("hello world"); 现在是myprint("hello world"); gets expanded to myprint_("hello world", BLACK) while myprint("hello world", 123456) gets expended to myprint_("hello world", 123456) . 被扩展为myprint_("hello world", BLACK)myprint("hello world", 123456)被扩展为myprint_("hello world", 123456)

While Frxstrem's answer is correct (and he/she has my upvote on it), too liberal use of preprocessor macros is a code smell. 尽管Frxstrem的答案是正确的(并且他/她对此表示赞同),但过于自由地使用预处理器宏是一种代码味道。 So the purists approach is to just declare two functions, one of which is a simple call through to the other: 因此,纯粹主义者的方法是只声明两个函数,其中一个是对另一个函数的简单调用:

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

void myprint(char* string) {
    myprint_color(string, kBackgroundColor);
}

This approach has two advantages: 这种方法有两个优点:

  1. It's very clear to a reader what's happening. 读者很清楚发生了什么事。

  2. You are not forced to provide all the functionality of the two functions within the body of a single one. 您不必被迫在单个函数体内提供这两个函数的所有功能。 I. e. you are free to implement it the other way round like this: 您可以像下面这样自由地实现它:

     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 */ } 

    With this approach, the simpler function really avoids setting the color, while the other really adds the relevant code, instead of always setting a color that defaults to black. 使用这种方法,较简单的函数实际上避免设置颜色,而另一个函数实际上添加了相关代码,而不是始终设置默认为黑色的颜色。

    You are free to use whichever approach is more convenient to implementing the functionality. 您可以自由使用任何一种更方便地实现功能的方法。 And you can decide later to change the implementation from one approach to the other without breaking code on the user side. 而且您可以稍后决定将实现方式从一种方法更改为另一种方法,而不会破坏用户端的代码。 Such a change cannot be done once you have preprocessor magic in place that provides the look and feel of a default argument. 一旦有了可以提供默认参数外观的预处理器魔术,就无法进行这种更改。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM