关于printf的有关问题,哪位高手能用printf的实现来解释一下
关于printf的问题,谁能用printf的实现来解释一下
代码执行起来
int main()
{
int a =1;
float b = 1.0;
float c = a/10;
//问题一:为什么不一样啊, 用%d输出b不是一次类型转换?
printf( "%d \n ", (int)(b));
printf( "%d \n " , b );
//这个更奇怪了,为什么,只是把第一个%d该成%f,后面的也会发生变化?
printf( "%d , %f , %f \n ", a/10 , b/10, c );
printf( "%f , %f , %f \n ", a/10 , b/10, c );
getch();
return 0;
}
会得到这样的结果:
1
0
0 , 0.100000 , 0.000000
-0.000000 , 0.000000 , -1.#QNAN0
小弟实在不解,望各位高人给点指教,谢谢了!
------解决方案--------------------
printf 函数不会对参数进行类型检查, 也就不会转换
------解决方案--------------------
int DEFUN(printf, (format), CONST char *format DOTS)
{
va_list arg;
int done;
va_start(arg, format);
done = vprintf(format, arg);
va_end(arg);
return done;
}
可以看到printf其实在内部调用的是vprintf,通过查看vprintf.c中的内容,我们可以看到vprintf其实是通过vfprintf实现的,它的函数原型是这样的:
int DEFUN(vfprintf, (s, format, args),
register FILE *s AND CONST char *format AND va_list args)
这个函数的整体执行结构是这样的:
register CONST char *f; //可以看到f是一个const char的指针
f = format;
while (*f != '\0 ')
{
...
if (*f != '% ')
{
...
}
if (*f == '% ')
{
fc = *f++;
...
switch (fc)
{
case 'd ':
...
case 'c ':
...
....
}
}
}
从上面的结构我们可以看出,函数首先读取字符串中的字符,然后一个个比较,如果是%,则马上用switch...case结构判断后续字符
在每一个case语句块里面,都有这样的语句:
nextarg(...);
outchar(...);
nextarg()是一个宏,有如下宏定义
#define castarg(var, argtype, casttype) \
var = (casttype) va_arg(args, argtype)
#define nextarg(var, type) castarg(var, type, type)
一出现va_arg,我们就很熟悉了,这个宏的作用就是读取可变参数,在这里的作用就是将args中的内容读入。也就是利用栈顶指针读取
代码执行起来
int main()
{
int a =1;
float b = 1.0;
float c = a/10;
//问题一:为什么不一样啊, 用%d输出b不是一次类型转换?
printf( "%d \n ", (int)(b));
printf( "%d \n " , b );
//这个更奇怪了,为什么,只是把第一个%d该成%f,后面的也会发生变化?
printf( "%d , %f , %f \n ", a/10 , b/10, c );
printf( "%f , %f , %f \n ", a/10 , b/10, c );
getch();
return 0;
}
会得到这样的结果:
1
0
0 , 0.100000 , 0.000000
-0.000000 , 0.000000 , -1.#QNAN0
小弟实在不解,望各位高人给点指教,谢谢了!
------解决方案--------------------
printf 函数不会对参数进行类型检查, 也就不会转换
------解决方案--------------------
int DEFUN(printf, (format), CONST char *format DOTS)
{
va_list arg;
int done;
va_start(arg, format);
done = vprintf(format, arg);
va_end(arg);
return done;
}
可以看到printf其实在内部调用的是vprintf,通过查看vprintf.c中的内容,我们可以看到vprintf其实是通过vfprintf实现的,它的函数原型是这样的:
int DEFUN(vfprintf, (s, format, args),
register FILE *s AND CONST char *format AND va_list args)
这个函数的整体执行结构是这样的:
register CONST char *f; //可以看到f是一个const char的指针
f = format;
while (*f != '\0 ')
{
...
if (*f != '% ')
{
...
}
if (*f == '% ')
{
fc = *f++;
...
switch (fc)
{
case 'd ':
...
case 'c ':
...
....
}
}
}
从上面的结构我们可以看出,函数首先读取字符串中的字符,然后一个个比较,如果是%,则马上用switch...case结构判断后续字符
在每一个case语句块里面,都有这样的语句:
nextarg(...);
outchar(...);
nextarg()是一个宏,有如下宏定义
#define castarg(var, argtype, casttype) \
var = (casttype) va_arg(args, argtype)
#define nextarg(var, type) castarg(var, type, type)
一出现va_arg,我们就很熟悉了,这个宏的作用就是读取可变参数,在这里的作用就是将args中的内容读入。也就是利用栈顶指针读取