· KLDP.org · KLDP.net · KLDP Wiki · KLDP BBS ·
CLanguage Variable Arguments List

C¾ð¾î °¡º¯ ÀÎÀÚ


printf()¿Í scanf()¿Í °°Àº °¡º¯ ÀÎÀÚ¸¦ ¹Þ´Â ÇÔ¼ö¸¦ ¸¸µé°Å³ª ÀÌ ÇÔ¼ö¸¦ µ¤¾î ¾²´Â wrapper¸¦ ¸¸µé·Á¸é °¡º¯ ÀÎÀÚ¸¦ ó¸®ÇÒ ÁÙ ¾Ë¾Æ¾ß ÇÕ´Ï´Ù.

°¡º¯ ÀÎÀÚ¸¦ ó¸®ÇÒ·Á¸é ´ÙÀ½°ú °°Àº data type°ú ÇÔ¼ö (¶Ç´Â ¸ÅÅ©·Î ÇÔ¼ö)¸¦ ½á¾ß ÇÕ´Ï´Ù:

  • va_list -- type
  • va_start(va_list argptr, last-arg) -- °¡º¯ ÀÎÀÚ Ã³¸® ½ÃÀÛ.
  • va_end(va_list argptr) -- °¡º¯ ÀÎÀÚ Ã³¸® ³¡.
  • T va_arg(va_list argptr, T) -- °¡º¯ ÀÎÀÚ ¾ò±â.

À̵éÀº ¸ðµÎ Ç¥ÁØ Çì´õ ÆÄÀÏÀÎ <stdarg.h>¿¡ ¼±¾ðµÇ¾î ÀÖ½À´Ï´Ù. ÀÏ´Ü °£´ÜÈ÷ N°³ÀÇ Á¤¼ö(int type)¸¦ ¹Þ¾Æ¼­ ´õÇÏ´Â ÇÔ¼ö¸¦ ¸¸µé¾î º¾½Ã´Ù:

#include <stdarg.h>

int
sum(int nargs, ...)
{
  va_list argptr;
  int i, total = 0;

  va_start(argptr, nargs);        /* °¡º¯ ÀÎÀÚ Ã³¸® ½ÃÀÛ */
  for (i = 0; i < nargs; i++)
    total += va_arg(argptr, int); /* Çϳª¾¿ °¡º¯ ÀÎÀÚ ¾ò±â */
  va_end(argptr);                 /* °¡º¯ ÀÎÀÚ Ã³¸® ³¡ */

  return total;
}


À§¿Í °°ÀÌ Á¤ÀÇÇØ ³õ°í ´ÙÀ½°ú °°ÀÌ ¾µ ¼ö ÀÖ½À´Ï´Ù (ÁÖÀÇ: sum()ÀÇ Ã¹¹ø° ÀÎÀÚ´Â µÎ¹ø°ºÎÅÍ ³ª¿Ã °¡º¯ ÀÎÀÚÀÇ °¹¼öÀÔ´Ï´Ù):

int sum(int nargs, ...);

int
main(void)
{
  int s1, s2;

  /* 1ºÎÅÍ 5±îÁö ´õÇÑ °ªÀ» s1¿¡ ÀúÀå. */
  s1 = sum(5, 1, 2, 3, 4, 5);

  /* 100, 200, 300À» ´õÇÑ °ªÀ» s2¿¡ ÀúÀå. */
  s2 = sum(3, 100, 200, 300);

  /* ... */
  return 0;
}


ÀÏ´Ü °¡º¯ ÀÎÀÚ¸¦ ó¸®Çϱâ À§Çؼ­´Â va_list typeÀÇ º¯¼ö Çϳª¸¦ ¼±¾ðÇØ¾ß ÇÕ´Ï´Ù:

va_list argptr;


±×¸®°í, °¡º¯ ÀÎÀÚ¸¦ ó¸®ÇÒ ºÎºÐ ¾Õ¿¡ ´ÙÀ½°ú °°ÀÌ ½á ÁÝ´Ï´Ù:

va_start(argptr, nargs);


va_start()ÀÇ Ã¹¹ø° ÀÎÀÚ´Â ¾Æ±î ¼±¾ðÇÑ va_list typeÀÇ º¯¼ö À̸§À̸ç, µÎ¹ø° ÀÎÀÚ´Â ÀÌ ÇÔ¼ö¿¡¼­ °¡º¯ ÀÎÀÚ¸¦ ¹Þ´Â ºÎºÐÀÇ ¹Ù·Î ¾ÕÀÇ (°íÁ¤µÈ) argumentÀÔ´Ï´Ù. Áï, À§¿¡¼­ ¿¹·Î µç sum()ÀÇ °æ¿ì, °¡º¯ ÀÎÀÚ¸¦ ³ªÅ¸³»´Â "..." ¾Õ¿¡ ¿À´Â argumentÀÎ nargs°¡ µÎ¹ø° ÀÎÀÚ°¡ µË´Ï´Ù.

´«Ä¡°¡ ºü¸¥ ºÐÀº ÀÌ¹Ì ¾Ë°í ÀÖ°ÚÁö¸¸, °¡º¯ ÀÎÀÚ¸¦ ¹Þ´Â ÇÔ¼ö´Â ¿©·¯ °¡Áö Á¦ÇÑÀÌ ºÙ½À´Ï´Ù. ù°, va_start()¿¡ °¡º¯ ÀÎÀÚ ¹Ù·Î ¾ÕÀÇ °íÁ¤µÈ ÀÎÀÚ¸¦ ÁÖ¾î¾ß Çϱ⠶§¹®¿¡, °¡º¯ ÀÎÀÚ¸¦ ¹Þ´Â ÇÔ¼ö´Â °íÁ¤µÈ ÀÎÀÚ°¡ Çϳª ÀÌ»ó ³ª¿Í¾ß ÇÕ´Ï´Ù. Áï, void foo(...)¿Í °°Àº ÇÔ¼ö´Â ¸¸µé ¼ö ¾ø½À´Ï´Ù. µÑ°, °¡º¯ ÀÎÀÚ¸¦ ³ªÅ¸³»´Â "..."´Â ¹Ýµå½Ã ¸¶Áö¸· ÀÎÀÚÀ̾î¾ß ÇÕ´Ï´Ù. "..."°¡ Áß°£À̳ª óÀ½¿¡ ³ª¿Ã ¼ö´Â ¾ø½À´Ï´Ù. ¿¹¸¦ µé¾î void bar(..., int a)¿Í °°Àº ÇÔ¼ö´Â ¸¸µé ¼ö ¾ø½À´Ï´Ù.

½ÇÁ¦ ÇÔ¼ö¿¡ Àü´ÞµÈ °¡º¯ ÀÎÀÚ¸¦ ¾ò±â À§Çؼ­´Â va_arg()¸¦ ºÒ·¯¼­ ó¸®ÇÕ´Ï´Ù. va_arg()´Â °¡º¯ ÀÎÀÚ·Î Àü´ÞµÈ °ªÀ» È£ÃâÇÒ ¶§¸¶´Ù Çϳª¾¿ ¾ò¾î¼­ ÁÝ´Ï´Ù. va_arg()´Â ù¹ø° ÀÎÀÚ·Î, va_start()·Î ÃʱâÈ­ÇÑ va_list typeÀ» ¹ÞÀ¸¸ç, µÎ¹ø° ÀÎÀڷδ °¡º¯ ÀÎÀÚ·Î Àü´ÞµÈ °ªÀÇ typeÀ» ½á ÁÖ¾î¾ß ÇÕ´Ï´Ù. ¿ì¸®°¡ ¸¸µç sum()ÀÇ °æ¿ì, ÇÔ¼öÀÇ ¸ñÀûÀÌ ¸ðµç int¸¦ ´õÇÑ °ªÀ» °è»êÇÏ´Â °ÍÀ̹ǷÎ, va_arg()ÀÇ µÎ¹ø° ÀÎÀÚ·Î int¸¦ ÁÖ¸é µË´Ï´Ù.

va_arg(argptr, int);


´«Ä¡°¡ ´õ¿í ºü¸¥ ºÐÀÌ¸é ¾Æ½Ã°ÚÁö¸¸, ¿©±â¼­ °¡º¯ ÀÎÀÚ¸¦ ¹Þ´Â ÇÔ¼ö¿¡ ¶Ç´Ù¸¥ Á¦ÇÑÀÌ ºÙ½À´Ï´Ù. ¾Æ½Ã°ÚÁö¸¸, °¡º¯ ÀÎÀÚ·Î Àü´ÞµÇ´Â °ªÀÇ Å¸ÀÔ¿¡´Â Á¦ÇÑÀÌ ¾ø½À´Ï´Ù (printf(), scanf()¸¦ »ý°¢Çغ¸¼¼¿ä). ¾Æ½±°Ôµµ va_arg()´Â Àü´ÞµÇ´Â °ªÀÇ Å¸ÀÔÀ» ¾Ë¾Æ³¾ ¹æ¹ýÀÌ ¾ø½À´Ï´Ù. µû¶ó¼­ ¹Ì¸® ±× typeÀ» ¾Ë¾Æ¼­ va_arg()ÀÇ µÎ¹ø° ÀÎÀÚ·Î Àü´ÞÇØ ÁÖ¾î¾ß ÇÕ´Ï´Ù.

°Ô´Ù°¡, °¡º¯ ÀÎÀÚ¸¦ ¹Þ´Â ÇÔ¼öÀÇ ÀÔÀå¿¡¼­, ¸î°³ÀÇ °¡º¯ ÀÎÀÚ°¡ Àü´ÞµÇ¾ú´ÂÁö ¾Ë¾Æ³¾ ¹æ¹ýÀº ¾ø½À´Ï´Ù. µû¶ó¼­ °íÁ¤µÈ ÀÎÀÚ·Î °¡º¯ ÀÎÀÚÀÇ °¹¼ö¸¦ Àü´ÞÇÏ´Â µî (À§ÀÇ sum()ÀÇ ¿¹Ã³·³)ÀÇ ¹æ¹ýÀ¸·Î va_arg()¸¦ ¸î¹øÀ» ºÒ·¯¾ß µÇ´Â°¡¸¦ ¾Ë¾Æ³¾ ¹æ¹ýÀ» Á¦°øÇØ¾ß ÇÕ´Ï´Ù.

´õ °ñÄ¡ ¾ÆÇ °ÍÀº va_arg()ÀÇ µÎ¹ø° ÀÎÀÚ·Î ¾µ ¼ö ÀÖ´Â type¿¡ Á¦ÇÑÀÌ ÀÖ´Ù´Â °ÍÀÔ´Ï´Ù. ÀÌ°Ç µÚ¿¡¼­ ´Ù·ç°Ú½À´Ï´Ù.

ÀÌÁ¦ °¡º¯ ÀÎÀÚ¸¦ ó¸®ÇÏ´Â ÇÔ¼ö¸¦ ¸¸µé¾î º¸¾ÒÀ¸´Ï, printf()ÀÇ wrapper¸¦ ¸¸µé¾î º¾½Ã´Ù.

³ëÆĽɿ¡¼­ ¸»¾¸µå¸®Áö¸¸, ´ÙÀ½°ú °°Àº ÇÔ¼ö´Â µ¿ÀÛÇÏÁö ¾Ê½À´Ï´Ù:

int
my_printf(const char *fmt, ...)
{
  return printf(fmt, ...);
}


ÀÏ´Ü ¸ÕÀú, printfÀÇ °è¿­¿¡´Â ´ÙÀ½°ú °°Àº ÇÔ¼öµéÀÌ ÀÖ´Ù´Â °ÍÀ» ¾Ë¾ÆµÓ½Ã´Ù:

int printf(const char *fmt, ...);
int fprintf(FILE fp, const char *fmt, ...);
int sprintf(char *sr, const char *fmt, ...);
int snprintf(char *s, size_t n, const char *fmt, ...);
/* ÀÌ»ó <stdio.h>¿¡ ¼±¾ðµÇ¾î ÀÖ´Â ÇÔ¼öµé */

int vprintf(const char *fmt, va_list ap);
int vfprintf(FILE fp, const char *fmt, va_list ap);
int vsprintf(char *sr, const char *fmt, va_list ap);
int vsnprintf(char *s, size_t n, const char *fmt, va_list ap);
/* ÀÌ»ó <stdarg.h>¿¡ ¼±¾ðµÇ¾î ÀÖ´Â ÇÔ¼öµé */


Àß º¸¸é ¾Ë°ÚÁö¸¸, <stdarg.h>¿¡ ÀÖ´Â ÇÔ¼öµéÀº <stdio.h>¿¡ ÀÖ´Â printf() °è¿­ ÇÔ¼ö À̸§ ¾Õ¿¡ 'v'°¡ ºÙ°í, "..." ´ë½Å¿¡ va_list typeÀÇ ÀÎÀÚ°¡ ¿Â´Ù´Â °ÍÀ» ¾Ë ¼ö ÀÖ½À´Ï´Ù.

printf() styleÀÇ ¹®ÀÚ¿­À» ¹ÞÀ¸·Á¸é, ÀÌ v*printf() °è¿­ÀÇ ÇÔ¼ö¸¦ ¾²¸é Æí¸®ÇÕ´Ï´Ù. ¿¹¸¦ µé¾î ´Ü¼øÈ÷ printf()¿Í ¶È°°Àº ±â´ÉÀ» ÇÏ´Â wrapper´Â ´ÙÀ½°ú °°ÀÌ ¸¸µé ¼ö ÀÖ½À´Ï´Ù:

int
my_printf(const char *fmt, ...)
{
  va_list argptr;
  int ret;

  va_start(argptr, fmt);
  ret = vprintf(fmt, argptr);
  va_end(argptr);

  return ret;
}


Áï, °¡º¯ ÀÎÀÚ Ã³¸®¸¦ À§ÇÑ va_list type º¯¼ö¸¦ ¼±¾ð, va_start()·Î ÃʱâÈ­ÇÑ ´ÙÀ½¿¡ v*printf() °è¿­ÀÇ ÇÔ¼ö¿¡ ÀÌ va_list typeÀÇ º¯¼ö¸¦ ³Ñ°ÜÁֱ⸸ ÇÏ¸é µË´Ï´Ù. (va_end()¸¦ ºÒ·¯ ³¡³»´Â °ÍÀ» ÀØÁö ¸¶¼¼¿ä!!)

Á»´õ º¹ÀâÇÏ°Ô Çϳª ´õ ¸¸µé¾î º¾½Ã´Ù. ÇÔ¼ö´Â error()ÀÔ´Ï´Ù. ÀÌ ÇÔ¼ö´Â ÁÖ¾îÁø printf() styleÀÇ ¿¡·¯ ¸Þ½ÃÁö¸¦ ¹Þ¾Æ¼­ stderr·Î Ãâ·ÂÇÏ°í, ÇÊ¿äÇϸé errnoÀÇ ³»¿ëµµ ¾Ë·ÁÁÖ°í, ÇÊ¿äÇϸé exit()¸¦ ºÒ·¯¼­ ÇÁ·Î±×·¥À» Á¾·áÇÏ´Â ÇÔ¼öÀÔ´Ï´Ù. ¼±¾ðÀº ´ÙÀ½°ú °°½À´Ï´Ù:

void error(int status, int ecode,
           const char *fmt, ...);


ÀÌ ÇÔ¼ö´Â ecode°¡ 0ÀÌ ¾Æ´Ñ °æ¿ì, strerror(ecode) °ªÀ» Ãâ·ÂÇÏ°í, fmt¿Í "..."À¸·Î Àü´ÞµÈ printf() styleÀÇ ¿¡·¯ ¸Þ½ÃÁöµµ Ãâ·ÂÇÑ ´ÙÀ½, status°¡ 0ÀÌ ¾Æ´Ñ °æ¿ì, exit(status)¸¦ È£ÃâÇÕ´Ï´Ù. ÇÔ¼ö Á¤ÀÇ´Â ´ÙÀ½°ú °°½À´Ï´Ù.

void
error(int status, int ecode,
      const char *fmt, ...)
{
  va_list argptr;

  fflush(stdout);
  fprintf(stderr, "error: ");
  if (ecode)
    fprintf(stderr, "%s: ", strerror(ecode));

  va_start(argptr, fmt);
  vfprintf(stderr, fmt, argptr);
  va_end(argptr);

  fputc('\n', stderr);

  fflush(stderr);  /* redundant */

  if (status)
    exit(status);
}


´ÙÀ½°ú °°ÀÌ ¾µ ¼ö ÀÖ½À´Ï´Ù.

#include <stdio.h>
#include <errno.h>

...

void
foo(const char *filename)
{
  FILE *fp;
  fp = fopen(filename, "r");
  if (!fp)
    error(1, errno, "cannot open file %s.", filename);
  ...
}


Âü°í·Î ¿©±â¼­ ¿¹·Î ¸¸µç error()´Â GNU C library (glibc)¿¡ ÀÌ¹Ì Æ÷ÇԵǾî ÀÖ½À´Ï´Ù. ¿©±â¿¡¼­´Â Á»´õ °£·«È­Çؼ­ ¸¸µé¾î º» °ÍÀÌÁÒ. ½ÇÁ¦ ¿©·¯ºÐÀÇ Äڵ忡 <error.h>¸¦ Æ÷ÇÔ½ÃÅ°¸é À§ error()¸¦ Á¤ÀÇÇÒ ÇÊ¿ä¾øÀÌ ¹Ù·Î ¾µ ¼ö ÀÖ½À´Ï´Ù. (Ãâ·Â ÇüÅ´ ¾à°£ ´Ù¸¦ ¼ö ÀÖ½À´Ï´Ù¸¸, ÀÎÀÚ typeÀ̳ª °¹¼ö´Â °°À¸´Ï ¶È°°ÀÌ ¾µ ¼ö ÀÖ½À´Ï´Ù)

¸¶Áö¸·À¸·Î ¾Æ±î va_arg()ÀÇ µÎ¹ø° ÀÎÀÚ·Î ³ª¿Ã ¼ö ÀÖ´Â type¿¡ Á¦ÇÑÀÌ ÀÖ´Ù°í Çߴµ¥ ±× ¾ê±â¸¦ Çغ¸°Ú½À´Ï´Ù. °á·ÐºÎÅÍ ¸»Çϸé, va_arg()ÀÇ µÎ¹ø° ÀÎÀÚ·Î ³ª¿Ã ¼ö ÀÖ´Â typeÀº ´ÙÀ½°ú °°½À´Ï´Ù:

  • int °è¿­ (int, unsigned int, signed int)
  • long °è¿­ (long, unsigned long, signed long)
  • double °è¿­ (double, long double)
  • Æ÷ÀÎÅÍ °è¿­ (¸ðµç ŸÀÔÀÇ Æ÷ÀÎÅÍ, ¿¹¸¦ µé¾î void *, char *, µîµî)

´ÙÀ½°ú °°Àº ŸÀÔÀº ¿Ã ¼ö ¾ø½À´Ï´Ù:

  • char °è¿­ (char, unsigned char, signed char)
  • short °è¿­ (short, unsigned short, signed short)
  • float °è¿­ (float)

±×·³ °¡º¯ ÀÎÀÚ·Î char³ª float typeÀº ¿Ã ¼ö ¾ø´À³Ä, ±×·¸Áö´Â ¾Ê½À´Ï´Ù. ÀÌ·± ŸÀÔÀ» ¹Þ±â À§Çؼ­´Â, va_arg()¿¡ ´ÙÀ½°ú °°ÀÌ Àü´ÞÇÕ´Ï´Ù.

  • char -> int (unsigned char´Â unsigned int, ÀÌ·± ½ÄÀ¸·Î)
  • short -> int (unsigned short´Â unsigned short, ÀÌ·± ½ÄÀ¸·Î)
  • float -> double

±× ÀÌÀ¯´Â ´ÙÀ½°ú °°½À´Ï´Ù. C ¾ð¾î°¡ óÀ½ ¸¸µé¾îÁú ¶§¿¡´Â function prototypeÀ̶õ°Ô ¾ø¾ú½À´Ï´Ù. ÀÎÀÚ°¡ ¸î°³ÀÌ°í, ¾î¶² ŸÀÔÀ̳Ŀ¡ »ó°ü¾øÀÌ ´Ü¼øÈ÷ ÇÔ¼ö°¡ ÀÖ°í, ¸®ÅÏ Å¸ÀÔÀÌ ¹¹´Ù. Á¤µµ¸¸ ¾Ë·Á ÁáÁÒ. ¿¹¸¦ µé¸é ´ÙÀ½°ú °°½À´Ï´Ù:

double bar();

double bar(a, f, ch)
  int a;
  float f;
  char ch;
{
  ...
}


ÀÌ·± ½ÄÀ¸·Î ÇÔ¼ö¸¦ ¼±¾ðÇÏ°Ô µÇ¸é, ÄÄÆÄÀÏ·¯°¡ ÇÔ¼öÀÇ Á¤ÀǸ¦ º¸±â Àü¿¡´Â ÀÌ ÇÔ¼ö¿¡ Àü´ÞµÇ´Â ÀÎÀÚÀÇ Å¸ÀÔÀÌ ¹ºÁö ¾Ë ¼ö ¾ø½À´Ï´Ù. ¸¸¾à ÄÄÆÄÀÏ·¯°¡ bar()ÀÇ Á¤ÀǸ¦ º¸±â Àü¿¡ ´ÙÀ½°ú °°Àº Äڵ带 ÄÄÆÄÀÏÇØ¾ß ÇÑ´Ù°í °¡Á¤ÇØ º¸±â ¹Ù¶ø´Ï´Ù:

void
foo(void)
{
  bar(4, 2.5, 9);
}


ÀÏ´Ü bar()ÀÇ ÀÎÀÚ°¡ 3°³Àε¥,, "void bar();"¸¸ º¸°í¼­´Â ÀÎÀÚ°¡ ÀûÀýÇÏ°Ô Àü´ÞµÇ¾ú´ÂÁö ¾Ë ¹æ¹ýÀÌ ¾ø½À´Ï´Ù. µû¶ó¼­ ÀÎÀÚ °¹¼ö üũ¸¦ ÇÒ ¼ö ¾ø½À´Ï´Ù.

µÑ°·Î, °¢°¢ÀÇ ÀÎÀÚ°¡ ¾Ë¸Â´Â ŸÀÔÀÎÁöµµ ¾Ë ¼ö ¾ø½À´Ï´Ù. ÇÔ¼ö È£ÃâÀ» À§Çؼ­´Â (stack¿¡ ÀÎÀÚ¸¦ pushÇØ¾ß Çϴµ¥), ÀÎÀÚÀÇ typeÀ» ¾Ë ¼ö ¾øÀ¸´Ï, ù¹ø° ÀÎÀÚÀÎ 4¸¦ pushÇÒ ¶§, 8 bit·Î 4¸¦ pushÇÒ °ÍÀÎÁö, 16 bit·Î 4¸¦ pushÇÒ °ÍÀÎÁö, 32 bit·Î ÇÒ °ÍÀÎÁö ¾Ë ¼ö°¡ ¾ø½À´Ï´Ù.

µû¶ó¼­ C ¾ð¾î¿¡´Â "integral promotion"À̶õ ¿ë¾î? °³³ä?ÀÌ ÀÖ°í, ¿©±â¿¡ µû¶ó¼­ ¸ðµç ÀÎÀÚ´Â ´ÙÀ½°ú °°Àº typeÀ¸·Î º¯È¯Çؼ­ stack¿¡ pushÇÕ´Ï´Ù.

  • char, short -> int
  • float -> double
  • int -> int (±×´ë·Î)
  • long -> long (±×´ë·Î)
  • double -> double (±×´ë·Î)
  • long double -> long double (±×´ë·Î)
  • ¸ðµç pointer type -> ¸ðµç pointer type (±×´ë·Î)

Áï, ÀÎÀÚ·Î Àü´ÞµÈ °ªÀÌ character °ªÀ̶ó ÇÒ Áö¶óµµ ÇÔ¼ö¸¦ È£ÃâÇÒ ¶§¿¡´Â int typeÀ¸·Î º¯È¯Çؼ­ Àü´ÞÇÕ´Ï´Ù.

Áö±Ý±îÁö´Â ANSI C¿¡¼­ function prototypeÀÌ ³ª¿À±â ÀüÀÇ old style (K&R) C¿¡ ÇÊ¿äÇÑ ³»¿ëÀÔ´Ï´Ù. ÀÚ, ANSI C¿¡¼­´Â function prototypeÀÌ ÀÖÀ¸´Ï, ÄÄÆÄÀÏ·¯°¡ ÇÔ¼ö È£ÃâÀ» Çϱâ Àü¿¡ ÇÔ¼öÀÇ ÀÎÀÚ °¹¼ö¿Í ŸÀÔÀ» ¸ðµÎ ¾Ë ¼ö ÀÖ½À´Ï´Ù.

double bar(int a, float f, char ch);


µû¶ó¼­ ´õ ÀÌ»ó ÀÌ·¯ÇÑ º¯È¯ÀÌ ÇÊ¿ä¾ø°Ô µÇ¾úÁö¸¸, Çϳª ¿¹¿Ü°¡ Àִµ¥, ¹Ù·Î °¡º¯ ÀÎÀÚ¸¦ ó¸®ÇÏ´Â ÇÔ¼öÀÔ´Ï´Ù. °¡º¯ ÀÎÀÚ´Â ½ÇÁ¦·Î ¾î¶°ÇÑ Å¸ÀÔÀÌ ¸î°³°¡ µé¾î¿Ã Áö ¾Ë ¼ö ¾ø±â ¶§¹®¿¡, ÀÌ·¯ÇÑ º¯È¯ÀÌ °è¼Ó ¼öÇàµË´Ï´Ù. µû¶ó¼­ va_arg()·Î ÀÌ·¯ÇÑ Å¸ÀÔÀ» ¹ÞÀ»·Á¸é ÀÌ integral conversionÀ» ¹Ì¸® »ý°¢ÇØ µÎ¾î¾ß ÇÕ´Ï´Ù.

¿¹¸¦ µé¾î ¹®ÀÚ Çϳª¾¿ ¹Þ¾Æ¼­ Ãâ·ÂÇÏ´Â ÇÔ¼ö¸¦ ¸¸µé¾î º¸°Ú½À´Ï´Ù:

void
putchars(int nargs, ...)
{
  va_list argptr;
  char ch;
  int i;

  va_starg(argptr, nargs);
  for (i = 0; i < nargs; i++) {
    ch = (char) va_arg(argptr, int);
    putchar(ch);
  }
  va_end(argptr);
}


Áï, µé¾î¿Ã °¡º¯ ÀÎÀÚ°¡ char typeÀÏÁö¶óµµ va_arg()¿¡¼­´Â integral promotion¿¡ µû¶ó int typeÀ¸·Î ¹Þ¾Æ¼­ ó¸®ÇØ¾ß ÇÕ´Ï´Ù.

Àß »ý°¢ÇØ º¸¸é, ÀÌ¹Ì ¿©±â¿¡ ´ëÇØ ¾Ë°í ÀÖ¾úÀ» °ÍÀÔ´Ï´Ù. printf()¿Í scanf()¸¦ »ý°¢Çغ¾½Ã´Ù.

printf¿¡¼­ floatÀ̳ª doubleÀ» Ãâ·ÂÇϱâ À§Çؼ­´Â "%f"¸¦ ¾¹´Ï´Ù. ±×·±µ¥, scanf¿¡¼­´Â floatÀº "%f", doubleÀº "%lf"¸¦ ¾¹´Ï´Ù. ¾Æ·¡ ¿¹ Âü°í:

double d;
float f;

printf("%f", d);
printf("%f", f);

scanf("%f", &f);
scanf("%lf", &d);


±× ÀÌÀ¯´Â, integral promotino¿¡ ÀÇÇØ printfÀÇ °æ¿ì, floatÀ» double·Î ¹Þ±â ¶§¹®ÀÔ´Ï´Ù. µû¶ó¼­ float°ú double¿¡ °üÇÑ Â÷ÀÌ°¡ ¾ø½À´Ï´Ù. ±×·¯³ª scanfÀÇ °æ¿ì¿¡´Â ¸ðµç ÀÎÀÚ°¡ pointer typeÀ̱⠶§¹®¿¡ ÀÌ·¯ÇÑ º¯È¯ÀÌ ÇÊ¿ä¾ø½À´Ï´Ù. Áï, ¸ðµç ŸÀÔÀ» °¢°¢ ±¸º°ÇØ¾ß ÇÏ´Â °ÍÀÌÁÒ.

ºÐ¸í printf ÄÚµå¾È¿¡¼­ floatÀ» Ãâ·ÂÇÏ´Â ºÎºÐÀº ´ÙÀ½°ú °°Àº Äڵ带 Æ÷ÇÔÇÕ´Ï´Ù:

  value = (float) va_arg(argptr, double);


¶ÇÇÑ scanf ÄÚµå ¾È¿¡¼­ floatÀ» Ãâ·ÂÇÏ´Â ºÎºÐÀº ´ÙÀ½°ú °°Àº Äڵ带 Æ÷ÇÔÇÕ´Ï´Ù:

  ptr = va_arg(argptr, float *);


ÀÌ Á¤µµ¸é °¡º¯ ÀÎÀÚ¸¦ ó¸®ÇÏ´Â ¹æ¹ýÀº ¿Ïº®È÷! ÀÍÈ÷¼ÌÀ» °ÍÀÔ´Ï´Ù. ±×·³ ´ÙÀ½ ±âȸ¿¡...

³¡ -- cinsk



  • TODO: Function prototypeÀÌ ANSI C¿¡¼­ ¼Ò°³µÈ °Í ¸Â³ª?
  • TODO: Integral PromotionÀ̶ó°í Çߴµ¥, ¿©±â¿¡ float, doubleÀÌ Æ÷ÇԵǴ °ÍÀÌ È®½ÇÇÑ°¡?
ÀÌ°Å ¾Ë¾Æº¸°í ±Û °íÄ¥ °Í.. -- cinsk.

ÇÔ¼ö ¼±¾ð(Á¤ÀÇ°¡ ¾Æ´Ñ)ÀÇ °æ¿ì¿¡´Â ±× Àü¿¡µµ ÀÖ¾ú´ø °Í °°½À´Ï´Ù. [http]http://www.ifi.uio.no/forskning/grupper/dsb/Programvare/Xite/ProgrammersManual/node11.html#SECTION000111000000000000000 ±×·¯³ª ¸Å°³º¯¼öÀÇ Å¸ÀÔµéÀ» ÇÔ²² Àû¾îÁÖ´Â function prototypeÀº ANSI C¿¡¼­ »õ·ÎÀÌ ³ª¿Â °ÍÀÎ µí ÇÕ´Ï´Ù.

°¡º¯ÀÎÀÚ ÇÔ¼ö¿¡¼­ Àû¿ëµÇ´Â °ÍÀº Integral PromotionÀ» Æ÷ÇÔÇÏ´Â Default argumnt promotionÀÔ´Ï´Ù.

C99 6.5.2.2 Function calls Áß¿¡¼­...

If the expression that denotes the called function has a type that does not include a prototype, the integer promotions are performed on each argument, and arguments that have type float are promoted to double. These are called the default argument promotions.

±×¸®°í Ç¥Áع®¼­¿¡¼­´Â Integer promotionÀ̶ó´Â ¿ë¾î¸¦ ¾¹´Ï´Ù.

Integer promotionÀº À̸§ ±×´ë·Î Á¤¼öÇüÀÇ ½Â±Þ¸¸À» ÀǹÌÇÕ´Ï´Ù. doubleÀ̳ª Æ÷ÀÎÅÍ´Â Æ÷ÇÔµÇÁö ¾Ê½À´Ï´Ù. intÇü ¶Ç´Â unsigned intÇüº¸´Ù rank°¡ ³·Àº (Áï Ç¥Çö¹üÀ§°¡ Á¼Àº) Á¤¼öÇü¿¡ ÇÑÇؼ­ int Çü ¶Ç´Â unsigned ÇüÀ¸·Î ½Â±ÞµË´Ï´Ù. ÇØ´çµÇÁö ¾Ê´Â µ¥ÀÌÅÍ ÇüµéÀº ±×´ë·Î ³²½À´Ï´Ù.

6.3.1.1 Boolean, characters, and integers Áß¿¡¼­...

The following may be used in an expression wherever an int or unsigned int may be used:

  • An object or expression with an integer type whose integer conversion rank is less than the rank of int and unsigned int.
  • A bit-field of type _Bool, int, signed int, or unsigned int.

If an int can represent all values of the original type, the value is converted to an int; otherwise, it is converted to an unsigned int. These are called the integer promotions. All other types are unchanged by the integer promotions.



°¡º¯ ÀÎÀÚ ¸ÅÅ©·Î


ISO C Ç¥ÁØÀ» Áö¿øÇÏ´Â ÄÄÆÄÀÏ·¯¿¡¼­´Â °¡º¯ ÀÎÀÚ¸¦ ó¸®ÇÏ´Â ¸ÅÅ©·Îµµ Á¤ÀÇÇÒ ¼ö ÀÖ½À´Ï´Ù. ÇÔ¼ö ÇüÅÂÀÇ ¸ÅÅ©·Î¸¦ Á¤ÀÇÇÒ ¶§, "..."À» ½á ÁÖ°í, ¸ÅÅ©·Î Á¤ÀÇ ºÎºÐ¿¡¼­ VA_ARGS¸¦ ½áÁÖ¸é ±× ÀÚ¸®¿¡ È®ÀåµË´Ï´Ù. ¿¹¸¦ µé¸é, ´ÙÀ½°ú °°½À´Ï´Ù:

#define debug(s, ...)    fprintf(stderr, s, __VA_ARGS__)

void
foo(void)
{
  debug("Entered the function, %s\n", __func__);
  /* ... */
}


°£´ÜÇÏ°Ô printf ÇüÅÂÀÇ ¸Þ½ÃÁö¸¦ ÀԷ¹ÞÀº Ç¥ÁØ ÇÔ¼ö assert()¿Í ºñ½ÁÇÑ ¸ÅÅ©·Î ÇÔ¼ö¸¦ ¸¸µé¾î º¾½Ã´Ù; ÇÔ¼ö À̸§Àº ASSERT()·Î ÇÏ°Ú½À´Ï´Ù. ASSERT()ÀÇ Ã¹ ÀÎÀÚ´Â, assert()ÀÇ ÀÎÀÚ¿Í °°½À´Ï´Ù. Áï °ÅÁþÀÎ °æ¿ì, abort()¸¦ ºÎ¸¨´Ï´Ù. ASSERT()ÀÇ µÎ¹ø° ÀÎÀÚºÎÅÍ´Â printf()¿Í °°½À´Ï´Ù. ¶ÇÇÑ NDEBUG ¸ÅÅ©·Î°¡ Á¤ÀÇµÈ °æ¿ì, ASSERT()´Â ¾Æ¹«·± ¿µÇâÀ» ÁÖÁö ¾Ê½À´Ï´Ù.

ÀÏ´Ü, ASSERT()°¡ ¾²ÀÎ ½ÃÁ¡ÀÇ ÆÄÀÏ À̸§, ÁÙ ¹øÈ£, ±×¸®°í ÇÔ¼ö À̸§À» ÀÚµ¿À¸·Î Ãâ·ÂÇÏ°Ô ÇսôÙ. µû¶ó¼­ ¹Ì¸® Á¤ÀÇµÈ ¸ÅÅ©·ÎÀÎ FILE°ú LINEÀ» ¾²¸ç, ¹Ì¸® Á¤ÀÇµÈ À̸§, func¸¦ ¾¹´Ï´Ù.

¾Æ·¡¿¡ ASSERT()ÀÇ Á¤ÀÇ°¡ ³ª°©´Ï´Ù:

#ifndef NDEBUG
# define ASSERT(exp, s, ...)  assert_(__FILE__, __LINE__, __func__, \
                                      #exp, s, __VA_ARGS__)
#else
# define ASSERT(exp, s, ...)  ((void)0)
#endif /* NDEBUG */


°£´ÜÇÕ´Ï´Ù. NDEBUG°¡ Á¤ÀÇµÈ °æ¿ì¿¡´Â ASSERT()°¡ assert_()¸¦ È£ÃâÇÕ´Ï´Ù. assert_()ÀÇ Ã³À½ ¼¼ ÀÎÀÚ´Â ASSERT()¸¦ ºÎ¸¥ °÷ÀÇ ÆÄÀÏ À̸§, ÁÙ ¹øÈ£, ÇÔ¼ö À̸§À» ÀÚµ¿À¸·Î Àü´ÞÇÏ°Ô µË´Ï´Ù. ´ÙÀ½À¸·Î ASSERT()ÀÇ Ã¹ ÀÎÀÚ¸¦ ¹®ÀÚ¿­·Î ¹Ù²Ù¾î Àü´ÞÇϸç(#exp), ±× ´ÙÀ½À¸·Î, printf() ½ºÅ¸ÀÏÀÇ format stringÀÎ s°¡ µé¾î¿À¸ç, ±× µÚ¿¡ °¡º¯ ÀÎÀÚ°¡ µé¾î¿É´Ï´Ù.

ÀÌÁ¦ assert_()ÀÇ Á¤ÀÇ°¡ ³ª°©´Ï´Ù:

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

void
assert_(const char *filename, int lineno, const char *func,
        const char *exp, const char *fmt, ...)
{
  va_list argptr;

  fflush(stdout);
  fprintf(stderr, "%s:%d: assertion, (%s) failed in function, %s\n",
          filename, lineno, exp, func);
  fprintf(stderr, "\treason: ");
  va_start(argptr, fmt);
  vfprintf(stderr, fmt, argptr);
  va_end(argptr);
  putc('\n', stderr);
  abort();
}


¿¹¸¦ µé¾î ´ÙÀ½ ÇÔ¼ö¸¦ »ý°¢ÇØ º¾½Ã´Ù:
void
set_age(int age)
{

ASSERT(age > MIN_AGE, "age should be larger than %d.", MIN_AGE);
/* ... */

}
MIN_AGE´Â 10À¸·Î Á¤ÀÇµÈ ¸ÅÅ©·ÎÀÌ°í, »ç¿ëÀÚ°¡ set_age(3)À» È£ÃâÇß´Ù¸é, ´ÙÀ½°ú °°Àº ASSERTionÀÌ ¹ß»ýÇÕ´Ï´Ù:

tmp.c:36: assertion, (age > minimum) failed in function, set_age
        reason: age should be larger than 10.
Aborted


ÀÚ, ±×·° Àú·° ASSERT() ¾µ¸¸ÇÏÁÒ? assert()º¸´Ù´Â Á» ³ªÀ» °Í °°½À´Ï´Ù.

Âü°í: ISO C Ç¥ÁØ 6.4.2.2, 6.10.3

±×·³ ¶Ç ´ÙÀ½ ±âȸ¿¡.. -- cinsk





sponsored by andamiro
sponsored by cdnetworks
sponsored by HP

Valid XHTML 1.0! Valid CSS! powered by MoniWiki
last modified 2005-04-12 22:35:12
Processing time 0.0120 sec