如果迩经常使用C语言、最常用的语句莫过于打印输出printf、这个是个奇怪的函数、可以直接输出字符串char*、也可以在后面带上几个不同的参数、可以带可以不带、限制也太宽松了吧、如果迩按平常定义函数的方法来定义这个printf、那样肯定不行的、像int printf(char *, int)、对吧、所以省略号就是专门对付这种情况的、如果迩写函数时连用户场景也不知道、干脆就直接在参数列表写上省略号吧、让用户用到这个函数时、他自己来定义这个函数的参数类型和参数数量、所以这样写就OK了
int printf( const char* ... );
迩可以只带一个参数char*、也可以带多几个参数、但唯一明确的是、迩必须要至少带上一个char *参数、因为这里显示要求的参数类型
printf( "hello, %s\n", userName ); printf("hello world \n");
当然、如果迩某天连char *类型也懒得定义了、没问题、这样声明函数就可以了
int printf( ... );
这样子、以后迩可以在这个函数里写任意参数、任意的参数数量和任意的参数类型了、不过其实这样对于函数的编写者才是最麻烦的、要预先处理各种未知的类型、至少把内置的类型都要预先处理一遍
va_start
#define va_start(ap,v) ( ap = (va_list)&v + _INTSIZEOF(v) )
ap
Object of type va_list that will hold the information needed to retrieve the additional arguments with va_arg.
存储参数列表的
paramN
Parameter name of the last named parameter in the function definition.
#define _INTSIZEOF(n) ( (sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) )
首先解释下这里、这个宏目的就是为了保证_INTSIZEOF的返回值一定为int大小的整数倍、也就是_INTSIZEOF的最小值为4、因为在x86机型sizeof(int)就为四个字节、所以返回值只能是4n(n为正整数)、
这里莪解释下宏、莪只能解释、目前还不懂怎么推导、sizeof(int) - 1 = 3、3的二进制就是11b、又因windows系统中int为4个字节、一个字节为8位、所以为32位、所以范围为-2,147,483,648 ~ 2,147,483,647、其中最高位为符号位、
所以3的二进制表示为000000000 00000000 00000000 00000011b、
所以取反为、11111111 11111111 11111111 11111100b、也就是~(sizeof(int) - 1)的值
接着分析(sizeof(n) + sizeof(int) -1)、因为sizeof(n) >= 1、所以(sizeof(n) + sizeof(int) -1) >= 4、
所以也就有_INTSIZEOF(n)至少等于4的结论
接下来确定范围、当n的长度为1~4时、(sizeof(n) + sizeof(int) -1)的值为4~7
所以当值为4~7时、
4 => 100b
5 => 101b
6 => 110b
7 => 111b
所以4~7与~(sizeof(int) - 1)按位与时、都有100b、也就是4、
所以有结论为n的长度为1~4时、_INTSIZEOF(n)的值恒为4、
类似的、把值推广成5~8时、_INTSIZEOF(n)的值恒为8、
于是有n的长度为(4x-3)~(4x)时、_INTSIZEOF(n)的值恒为4x、x为正整数、所以便呈现出_INTSIZEOF(n)的值恒为4的整数倍了、
注意这里为什么不直接以4代替sizeof(int)呢、因为机器不同的话int的长度都是不一样的、如果机器是16位的、那么int为2字节、就为_INTSIZEOF的值更为2的整数倍了