免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 3288 | 回复: 4

[C] printf中可变参数的问题 [复制链接]

论坛徽章:
9
寅虎
日期:2013-12-02 12:49:22巨蟹座
日期:2014-07-18 18:13:34卯兔
日期:2014-07-25 14:43:08子鼠
日期:2014-07-26 10:10:51酉鸡
日期:2014-07-31 15:09:562015亚冠之本尤德科
日期:2015-05-19 09:27:382015亚冠之卡尔希纳萨夫
日期:2015-06-20 10:30:212015亚冠之阿尔纳斯尔
日期:2015-07-01 20:46:062015亚冠之城南
日期:2015-07-15 21:12:00
发表于 2014-07-16 13:50 |显示全部楼层
本帖最后由 lifayi2008 于 2014-07-16 14:54 编辑

printf中可变参数的处理需要这样一些宏定义
  1. /* stdarg.h standard header */
  2. #ifndef _STDARG
  3. #define _STDARG

  4. /* type definitions */
  5. typedef char *va_list;
  6. /* macros */
  7. #define va_arg(ap, T) \                                /*从ap指向的地址处,按照T数据类型返回对应的指针,然后将指针指向T按照int对齐后的地址*/
  8.         (* (T *)(((ap) += _Bnd(T, 3U)) - _Bnd(T, 3U)))
  9. #define va_end(ap) (void)0                                            /*将ap指向NULL*/
  10. #define va_start(ap, A) \                                              /*将ap指针指向A后面一个元素的开始,A也按照int对齐*/
  11.         (void)((ap) = (char *)&(A) + _Bnd(A, 3U))
  12. #define _Bnd(X, bnd) (sizeof (X) + (bnd) & ~(bnd))       /*将X类型的数据所占的内存空间按照bnd+1对齐*/
  13. #endif
复制代码
这是linux c一站式编程中的简化实现版

我想问一下 为什么va_arg()宏 可以将ap指针指向  T按照int  对齐后的下一个参数开始的地方


原文中的printf简化实现
  1. #include <stdio.h>
  2. #include <stdarg.h>

  3. void myprintf(const char *format, ...)
  4. {
  5.      va_list ap;
  6.      char c;

  7.      va_start(ap, format);
  8.      while (c = *format++) {
  9.           switch(c) {
  10.           case 'c': {
  11.                /* char is promoted to int when passed through '...' */
  12.                char ch = va_arg(ap, int);
  13.                putchar(ch);
  14.                break;
  15.           }
  16.           case 's': {
  17.                char *p = va_arg(ap, char *);
  18.                fputs(p, stdout);
  19.                break;
  20.           }
  21.           default:
  22.                putchar(c);
  23.           }
  24.      }
  25.      va_end(ap);
  26. }

  27. int main(void)
  28. {
  29.      myprintf("c\ts\n", '1', "hello");
  30.      return 0;
  31. }
复制代码

论坛徽章:
324
射手座
日期:2013-08-23 12:04:38射手座
日期:2013-08-23 16:18:12未羊
日期:2013-08-30 14:33:15水瓶座
日期:2013-09-02 16:44:31摩羯座
日期:2013-09-25 09:33:52双子座
日期:2013-09-26 12:21:10金牛座
日期:2013-10-14 09:08:49申猴
日期:2013-10-16 13:09:43子鼠
日期:2013-10-17 23:23:19射手座
日期:2013-10-18 13:00:27金牛座
日期:2013-10-18 15:47:57午马
日期:2013-10-18 21:43:38
发表于 2014-07-16 14:58 |显示全部楼层
不是有 += 么,这个改变了ap。

论坛徽章:
9
寅虎
日期:2013-12-02 12:49:22巨蟹座
日期:2014-07-18 18:13:34卯兔
日期:2014-07-25 14:43:08子鼠
日期:2014-07-26 10:10:51酉鸡
日期:2014-07-31 15:09:562015亚冠之本尤德科
日期:2015-05-19 09:27:382015亚冠之卡尔希纳萨夫
日期:2015-06-20 10:30:212015亚冠之阿尔纳斯尔
日期:2015-07-01 20:46:062015亚冠之城南
日期:2015-07-15 21:12:00
发表于 2014-07-16 15:07 |显示全部楼层
后面还有个  -   啊回复 2# hellioncu


   

论坛徽章:
324
射手座
日期:2013-08-23 12:04:38射手座
日期:2013-08-23 16:18:12未羊
日期:2013-08-30 14:33:15水瓶座
日期:2013-09-02 16:44:31摩羯座
日期:2013-09-25 09:33:52双子座
日期:2013-09-26 12:21:10金牛座
日期:2013-10-14 09:08:49申猴
日期:2013-10-16 13:09:43子鼠
日期:2013-10-17 23:23:19射手座
日期:2013-10-18 13:00:27金牛座
日期:2013-10-18 15:47:57午马
日期:2013-10-18 21:43:38
发表于 2014-07-16 15:12 |显示全部楼层
lifayi2008 发表于 2014-07-16 15:07
后面还有个  -   啊回复 2# hellioncu


你数数括号,那个-不修改ap

论坛徽章:
9
寅虎
日期:2013-12-02 12:49:22巨蟹座
日期:2014-07-18 18:13:34卯兔
日期:2014-07-25 14:43:08子鼠
日期:2014-07-26 10:10:51酉鸡
日期:2014-07-31 15:09:562015亚冠之本尤德科
日期:2015-05-19 09:27:382015亚冠之卡尔希纳萨夫
日期:2015-06-20 10:30:212015亚冠之阿尔纳斯尔
日期:2015-07-01 20:46:062015亚冠之城南
日期:2015-07-15 21:12:00
发表于 2014-07-16 15:50 |显示全部楼层
感谢  理解了回复 4# hellioncu


   
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP