Friday, January 21, 2011

[ZZ]printf是一个神奇的函数

第一优先准则是计算++
这是C++的++体现的地方(开玩笑的^_^),有++的地方先执行
第二优先准则是程序译码原理:
译码是由右往左译的,貌似所有编译器都是那样
printf("%d\n%d\n%d\n%d\n",*p, *p++, *p++, *p);
优先执行++,然后从右开始,所以第一句执行的是第三位置的*p++
优先执行++,所以第二句执行的是第二位置的*p++
类似了后面
另外也就是因为++优先级是奇高,所以*p++ = *(p++)
这就不用我说了吧,和printf就没关系

--------------------------

可变形参的实现是通过堆栈来完成的,函数在堆栈里去拿数据,不过根据了不同的机器做了一些偏移

贴一下libc里面printf的实现

int
printf(const char *format, ...)
{
va_list ap;
int retval;

va_start(ap, format);
retval = _doprnt(format, ap, stdout);

va_end(ap);

return retval;
}

typedef char * va_list;
#define _INTSIZEOF(n) \ //n 为 char *
((sizeof(n)+sizeof(int)-1)&~(sizeof(int) - 1) ) //这个值为4 (32bit机器)
#define va_start(ap,v) ( ap = (va_list)&v + _INTSIZEOF(v) ) //偏移4bytes
#define va_end(ap) ( ap = (va_list)0 )

*p++在有些编译器实现的时候很可能额外开栈,从而导致最后一个参数(实际上第一个传递)和看到的不同,实际上完成的是两个动作:

q=*p; p=p+1;

因此编译器拿数据取值的时候就不一致了,可变形参的这种问题不同编译器处理是不一样的。