MIT OS 4. printf vsprint fprintf 格式化输出 @ Lab1
来源:互联网 发布:炫浪网络社区下载 编辑:程序博客网 时间:2024/06/03 20:53
关于可变参数这里讲的很明白: http://www.cppblog.com/qiujian5628/archive/2012/02/01/41562.html
主要是C语言函数调用参数入栈顺序和va_list宏。
--> va_start(ap,所有参数中第一个参数) ap指向参数列表,是一个地址。
--->va_arg(ap,type) ap改变,指向下一个参数,type是当前参数的类型
--->va_end 清除ap,就是ap指向NULL
另外还有一个扩展宏 va_cp。
Macro: void __va_copy (va_list dest, va_list src)
- The __va_copy macro allows copying of objects of type va_list even if this is not an integral type. The argument pointer in dest is initialized to point to the same argument as the pointer in src.
This macro is a GNU extension but it will hopefully also be available in the next update of the ISO C standard.
If you want to use __va_copy you should always be prepared for the possibility that this macro will not be available. On architectures where a simple assignment is invalid, hopefully __va_copy will be available, so one should always write something like this:
{ va_list ap, save; ...#ifdef __va_copy __va_copy (save, ap);#else save = ap;#endif ...}
关于va_list 不同编译器和体系结构可能会有不同(http://stackoverflow.com/questions/988290/populating-a-va-list),例如JOS里面定义采用编译器自带方案:
typedef __builtin_va_list va_list;#define va_start(ap, last) __builtin_va_start(ap, last)#define va_arg(ap, type) __builtin_va_arg(ap, type)#define va_end(ap) __builtin_va_end(ap)
附上vsprintfmt.c内容:
void vprintfmt(void (*putch)(int, void*), void *putdat, const char *fmt, va_list ap){ register const char *p; register int ch, err; unsigned long long num; int base, lflag, width, precision, altflag; char padc; while (1) { while ((ch = *(unsigned char *) fmt++) != '%') { if (ch == '\0') return; putch(ch, putdat); } // Process a %-escape sequence padc = ' '; width = -1; precision = -1; lflag = 0; altflag = 0; reswitch: switch (ch = *(unsigned char *) fmt++) { // flag to pad on the right case '-': padc = '-'; goto reswitch; // flag to pad with 0's instead of spaces case '0': padc = '0'; goto reswitch; // width field case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': for (precision = 0; ; ++fmt) { precision = precision * 10 + ch - '0'; ch = *fmt; if (ch < '0' || ch > '9') break; } goto process_precision; case '*': precision = va_arg(ap, int); goto process_precision; case '.': if (width < 0) width = 0; goto reswitch;case '#': altflag = 1; goto reswitch; process_precision: if (width < 0) width = precision, precision = -1; goto reswitch; // long flag (doubled for long long) case 'l': lflag++; goto reswitch; // character case 'c': putch(va_arg(ap, int), putdat); break; // error message case 'e': err = va_arg(ap, int); if (err < 0) err = -err; if (err >= MAXERROR || (p = error_string[err]) == NULL) printfmt(putch, putdat, "error %d", err); else printfmt(putch, putdat, "%s", p); break; // string case 's': if ((p = va_arg(ap, char *)) == NULL) p = "(null)"; if (width > 0 && padc != '-') for (width -= strnlen(p, precision); width > 0; width--) putch(padc, putdat); for (; (ch = *p++) != '\0' && (precision < 0 || --precision >= 0); width--) if (altflag && (ch < ' ' || ch > '~')) putch('?', putdat); else putch(ch, putdat); for (; width > 0; width--) putch(' ', putdat); break; // (signed) decimal case 'd': num = getint(&ap, lflag); if ((long long) num < 0) { putch('-', putdat); num = -(long long) num; } base = 10; goto number; // unsigned decimal case 'u': num = getuint(&ap, lflag); base = 10; goto number; // (unsigned) octal case 'o': // Replace this with your code. putch('X', putdat); putch('X', putdat); putch('X', putdat); break; // pointer case 'p': putch('0', putdat); putch('x', putdat); num = (unsigned long long) (uintptr_t) va_arg(ap, void *); base = 16; goto number; // (unsigned) hexadecimal case 'x': num = getuint(&ap, lflag); base = 16; number: printnum(putch, putdat, num, base, width, padc); break; // escaped '%' character case '%': putch(ch, putdat); break; // unrecognized escape sequence - just print it literally default: putch('%', putdat); for (fmt--; fmt[-1] != '%'; fmt--) /* do nothing */; break; } }}...
- MIT OS 4. printf vsprint fprintf 格式化输出 @ Lab1
- PHP格式化输出printf,sprintf,vprintf,fprintf
- MIT OS 5. 小结@ Lab1
- MIT OS 2. Boot and Stack @Lab1
- MIT OS 3. Some Tips @ Lab1
- fprintf:格式化输出函数
- C语言--格式化输入/输出函数(printf/scanf,fprintf/fscanf,sprintf,sscanf)
- printf/fprintf/sprintf/snprintf输出函数
- printf 格式化输出
- printf 格式化输出
- printf()格式化输出详解
- printf格式化输出
- printf()的格式化输出
- printf 格式化输出控制
- printf格式化输出
- printf()格式化输出详解
- printf格式化输出字符串
- 格式化输出 printf() 详解
- 李开复雷军争抢移动互联网入口:难撼行业格局
- 启动JBoss出现“java.lang.noclassdeffounderror org/apache/commons/lang3/stringutils jar”解决
- 苹果官方推荐的应用软件
- maven仓库配置-经典
- clock_gettime参数介绍
- MIT OS 4. printf vsprint fprintf 格式化输出 @ Lab1
- 教你在Joomla正文中插入google廣告、圖片廣告
- 关于引用的指向的 问题小解
- MIDlet-Jar说明
- dedecms添加二级域名设置问题
- Java基础_线程_多线程
- 启动JBoss出现“java.lang.NoClassDefFoundError: org/apache/commons/lang/StringUtils”解决
- 在线考试系统设计时必须考虑的问题之四---------综合参数设置问题
- MyEclipse插件开发-在当前代码中增加main函数的插件