免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 2627 | 回复: 19
打印 上一主题 下一主题

高手请进:难道标准库STDARG.H是错的? [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2005-09-23 20:45 |只看该作者 |倒序浏览
难道标准库STDARG.H是错的?

大家都用过printf这个函数,知道它的参数个数是不定的。比如:
  1. printf("Char is %c, Int is %d.\n", c, i);
复制代码
因为参数个数不一定,所以除了第一个参数又命名,其他的都没有,要访问其他参数,是通过定位于第一个参数的地址,再加上相应的位移。比如说,第一个参数地址为n,长度为10,那么第二个参数地址即为n+10。
在标准库STDARG.H里,va_start(ap,v)把指针移动到第二个参数,那它是怎么知道第一个参数的长度呢?它用:
  1. #define _INTSIZEOF(n)   ( (sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) )
复制代码

我的疑问是:这样真能得到第一个参数的长度吗?因为va_start(ap,v)里的'v'实际上是个指针,所以_INTSIZEOF(n)里的'n'也是指针,sizeof得到的不是第一个参数的长度,而是指针变量(存储了第一个参数的地址)的长度。
[code]char *fmt = "Hello World!";
printf("%d", sizeof(fmt));
// 结果是4,很明显,它不可能是字符串"Hello World!",而是地址变量的长度。
真的不知道怎么解释。

论坛徽章:
0
2 [报告]
发表于 2005-09-23 21:04 |只看该作者

高手请进:难道标准库STDARG.H是错的?

开玩笑。一个是指针变量,一个是字符数组,每个指针在32位机上都是4字节,第二个是数组,sizeof运算符返回的是数组的字节数。

论坛徽章:
0
3 [报告]
发表于 2005-09-23 21:06 |只看该作者

高手请进:难道标准库STDARG.H是错的?

char fmt[50];
printf("%d", sizeof(fmt));

注意,数组名传给函数做参数时,将被转变成指针。

论坛徽章:
0
4 [报告]
发表于 2005-09-23 21:09 |只看该作者

高手请进:难道标准库STDARG.H是错的?

  1. #define _INTSIZEOF(n)   ( (sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) )
复制代码

我的疑问是:这样真能得到第一个参数的长度吗?

论坛徽章:
0
5 [报告]
发表于 2005-09-23 21:11 |只看该作者

高手请进:难道标准库STDARG.H是错的?

原帖由 "albcamus" 发表:
intf("%d", sizeof(fmt));

注意,数组名传给函数做参数时,将被转变成指针。

    这里并没有把数组名作为参数呀,这里是把sizeof(fmt)运算表达式的结果作为函数的参数。

论坛徽章:
0
6 [报告]
发表于 2005-09-23 21:14 |只看该作者

高手请进:难道标准库STDARG.H是错的?

原帖由 "albcamus" 发表:
intf("%d", sizeof(fmt));

注意,数组名传给函数做参数时,将被转变成指针。


版主老大,这里好像还没有这个问题嘛,人家是把sizeof(数组名)
传给函数,没有把数组名传给函数哈。。。

论坛徽章:
0
7 [报告]
发表于 2005-09-23 21:16 |只看该作者

高手请进:难道标准库STDARG.H是错的?

原帖由 "renstone921" 发表:

    这里并没有把数组名作为参数呀,这里是把sizeof(fmt)运算表达式的结果作为函数的参数。


我知道呀。楼主就是以为函数对待做为参数的数组和指针,其方式与sizeof操作符一样,才导致了这个误解。

论坛徽章:
0
8 [报告]
发表于 2005-09-23 21:27 |只看该作者

高手请进:难道标准库STDARG.H是错的?

有点晕!好象你们说得和我问得没什么关系??我的疑问是,sizeof(指针)这种方法能达到我们想达到的目的吗?
至于那个数组,只是我的一种猜测——会不会sizeof()里的不是指针,而是数组。因为是数组的话,的确是可以得到长度。仅此而已。

论坛徽章:
0
9 [报告]
发表于 2005-09-23 21:29 |只看该作者

高手请进:难道标准库STDARG.H是错的?

记得c陷阱与缺陷里面讲过这几个宏的事情,记不清了。
现在手头没有va_arg系列宏的代码,也无法查证楼主所说,
只能看着楼主的例子,没搞明白版主所指,。。。  

论坛徽章:
0
10 [报告]
发表于 2005-09-23 21:30 |只看该作者

高手请进:难道标准库STDARG.H是错的?

这是K&R-The C programming Language里的。我就是看这个产生的疑问,和大家探讨一下。
  1.    #include <stdarg.h>;

  2.    /* minprintf: minimal printf with variable argument list */
  3.    void minprintf(char *fmt, ...)
  4.    {
  5.        va_list ap; /* points to each unnamed arg in turn */
  6.        char *p, *sval;
  7.        int ival;
  8.        double dval;

  9.        va_start(ap, fmt); /* make ap point to 1st unnamed arg */
  10.        for (p = fmt; *p; p++) {
  11.            if (*p != '%') {
  12.                putchar(*p);
  13.                continue;
  14.            }
  15.            switch (*++p) {
  16.            case 'd':
  17.                ival = va_arg(ap, int);
  18.                printf("%d", ival);
  19.                break;
  20.            case 'f':
  21.                dval = va_arg(ap, double);
  22.                printf("%f", dval);
  23.                break;
  24.            case 's':
  25.                for (sval = va_arg(ap, char *); *sval; sval++)
  26.                    putchar(*sval);
  27.                break;
  28.            default:
  29.                putchar(*p);
  30.                break;
  31.            }
  32.        }
  33.        va_end(ap); /* clean up when done */
  34.    }
复制代码
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP