CLanguage Variable Arguments List
C¾ð¾î °¡º¯ ÀÎÀÚ ¶printf()¿Í scanf()¿Í °°Àº °¡º¯ ÀÎÀÚ¸¦ ¹Þ´Â ÇÔ¼ö¸¦ ¸¸µé°Å³ª ÀÌ ÇÔ¼ö¸¦ µ¤¾î ¾²´Â wrapper¸¦ ¸¸µé·Á¸é °¡º¯ ÀÎÀÚ¸¦ ó¸®ÇÒ ÁÙ ¾Ë¾Æ¾ß ÇÕ´Ï´Ù.
°¡º¯ ÀÎÀÚ¸¦ ó¸®ÇÒ·Á¸é ´ÙÀ½°ú °°Àº data 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Àº ´ÙÀ½°ú °°½À´Ï´Ù:
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ÇÕ´Ï´Ù.
Áö±Ý±îÁö´Â 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
ÇÔ¼ö ¼±¾ð(Á¤ÀÇ°¡ ¾Æ´Ñ)ÀÇ °æ¿ì¿¡´Â ±× Àü¿¡µµ ÀÖ¾ú´ø °Í °°½À´Ï´Ù.
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:
°¡º¯ ÀÎÀÚ ¸ÅÅ©·Î ¶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); /* ... */ }
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
|
Executive ability is prominent in your make-up. |