Mohammad
Mohammad

Reputation: 362

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

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.

I am a beginner C programmer.

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:

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

Upvotes: 0

Views: 157

Answers (2)

While Frxstrem's answer is correct (and he/she has my upvote on it), too liberal use of preprocessor macros is a code smell. 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.

Upvotes: 1

Freyja
Freyja

Reputation: 40804

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"); gets expanded to myprint_("hello world", BLACK) while myprint("hello world", 123456) gets expended to myprint_("hello world", 123456).

Upvotes: 4

Related Questions