C C++

가변인수를 가지는 함수 및 매크로 만들기

_침묵_ 2006. 4. 17. 23:50

================================================================================================

ANSI C버전

================================================================================================

#include <stdio.h>
#include <stdarg.h>

 

int average(int first, ...);

 

void main( void )
{
   /* Call with 3 integers (-1 is used as terminator). */
   printf("Average is: %d\n", average(2, 3, 4, -1));

 

   /* Call with 4 integers. */
   printf("Average is: %d\n", average(5, 7, 9, 11, -1));

 

   /* Call with just -1 terminator. */
   printf("Average is: %d\n", average(-1));

 

   getchar();
}

 

/* Returns the average of a variable list of integers. */
int average(intfirst, ...)
{
   int count = 0, sum = 0, i = first;
   va_list marker;

   va_start(marker, first);     /* Initialize variable arguments. */

   while (i != -1)
   {
      sum += i;
      count++;
     i= va_arg(marker,int);
   }
   va_end(marker);              /* Reset variable arguments.      */

   return (sum ? (sum / count) : 0);
}

 

================================================================================================

#include <stdio.h>
#include <string.h>
#include <stdarg.h>

 

void myprintf(char *sFirst, ...)
{
    va_list args;
    char *str;

   

    va_start(args, sFirst);
    printf("sFirst : %s\n", sFirst);

    while(1)
    {
         str = va_arg(args, char *);


         if (strcmp(str, "") == 0)
             break;
        else
        {
             printf("va_list: %s\n", str);
         }

    }


    str = va_arg(args, char *);
    va_end(args);
}

 

void main()
{
    myprintf("sbs", "mbc", "kbs", "");
    getchar();
}

================================================================================================

 

#include <stdarg.h>
#include <stdio.h>
 
#define ERR_FUNC(fmt, args...) err_func(__FILE__, __LINE__, fmt, ## args)
 
void err_func(const char *, const int, char *, ...); 
 
 
void err_func(const char *name, const int line, char *fmt, ...)
{
    va_list ap;
    va_start(ap, fmt);
    fprintf(stderr, "Error in %s, line %i:", name, line);
    vfprintf(stderr, fmt, ap);
    va_end(ap);
}
 
int main()
{
    ERR_FUNC("value=%d",12);
}

 

================================================================================================

GCC버전

================================================================================================
#include <stdarg.h>
#include <stdio.h>
 
#define ERR_FUNC(fmt, args...) err_func(__FILE__, __FUNCTION__, __LINE__, fmt, ## args)
 
void err_func(const char *, const char *, const int, char *, ...)
__attribute__ ((format (printf, 4, 5))); 
 
 
void err_func(const char *name, const char *func, const int line, char *fmt, ...)
{
    va_list ap;
 
    va_start(ap, fmt);
    fprintf(stderr, "Error in %s, line %i, in %s():", name, line, func);
    vfprintf(stderr, fmt, ap);
    va_end(ap);
}
 
int main()
{
    ERR_FUNC("value=%d",12);
}

================================================================================================

Token-Pasting Operator (##)

The double-number-sign or “token-pasting” operator (##), which is sometimes called the “merging” operator, is used in both object-like and function-like macros. It permits separate tokens to be joined into a single token and therefore cannot be the first or last token in the macro definition.

If a formal parameter in a macro definition is preceded or followed by the token-pasting operator, the formal parameter is immediately replaced by the unexpanded actual argument. Macro expansion is not performed on the argument prior to replacement.

Then, each occurrence of the token-pasting operator intoken-stringis removed, and the tokens preceding and following it are concatenated. The resulting token must be a valid token. If it is, the token is scanned for possible replacement if it represents a macro name. The identifier represents the name by which the concatenated tokens will be known in the program before replacement. Each token represents a token defined elsewhere, either within the program or on the compiler command line. White space preceding or following the operator is optional.

This example illustrates use of both the stringizing and token-pasting operators in specifying program output:

 

#define paster(n) printf("token" #n " = %d", token##n)int token9 = 9;
If a macro is called with a numeric argument like
paster(9);

 

the macro yields
printf("token" "9" " = %d", token9);

 

which becomes
printf("token9 = %d", token9);

출처:http://home.dasomnetwork.com/~leedw

'C C++' 카테고리의 다른 글

스트링 버퍼를 선언과 함께 초기화  (0) 2006.04.17
가변 인수  (0) 2006.04.17
[펌] Unix  (0) 2005.11.09