自从2014.7.9加入**软研以来,一直都做windows UI方面的开发,主要语言为C++;时间很快就过去了,一直都没时间也许是没精力写一些记录,但越觉得写写文档的必要性了;那么果断的申请了博客,记录下以前的,今后的程序生涯的点点滴滴,一是鼓励自己不断沉淀技术,职业文化等等;再者以后也有一个可以属于自己的书房可以翻阅,回忆。时间已经很晚了,眼睛有些朦胧;
刚看了看《系统程序猿的成长计划》,里面讲道了可变参数的简单机制剖析;大致就是一个压栈的匹配;
printf想必大家都会熟悉的使用;她就是典型的可变参数列表。。。。
int __cdecl printf (const char *format, ...);
可变参数,大约是这么模板化的,
1)他必须是在至少一个给定的参数后面出现;即 不能达到这样的牛叉的 printf(...);
2)前列参数后,逗号隔开,续"..."三个点,达到C语言的语法要求
这样的函数,即可叫可变参数函数;
void fun()
{
int i = 100, j = 200, k = 300, l = 400;
printf("%d, %d, %d", i, j, k, l);
}
系统会在栈区依次为l, k, j, i开辟空间;变量的申明是右向左依次展开的;
在我的win8 64位系统开辟的内存,依次为
+ &i 0x0018fe4c int *
+ &j 0x0018fe40 int *
+ &k 0x0018fe34 int *
+ &l 0x0018fe28 int *
他们是一个压栈的过程,栈的地址是向低地址延申的,但没搞明白为社么每次的间隔是12?!!也请朋友八卦一下;
l,k,j,i依次压栈;我觉得三个%d,或许也会压栈另一个栈;
栈 A 栈B
+ &i 0x0018fe4c int * %d
+ &j 0x0018fe40 int * %d
+ &k 0x0018fe34 int * %d
+ &l 0x0018fe28 int *
两个栈依次取值,去第一个%d,去&i;---》去第2个%d,去&j;---》去第3个%d,去&k;---》....所以k没办法打印了
打出结果确实是:
100, 200, 300
当然printf可能是这样的压栈对比出栈;自己写可变参数的函数时,可以借助参数的个数,即第一个参数把可变的参数个数穿进去;这样会以指针进行后续的查找;
其实很简单,比如add(int num, ...)
add(1, 100);
add(2, 20, 30);
add(4, 1, 2, 3, 5);
指针直接定位到第一个参数;即参数1的地址,加法运算;指针偏移下个参数的字节,再接着加。。。。直到最后一个参数加完。
这就证明了,很多东西是很有意思的,我们真的不能老四抱怨什么都不会,什么都不懂,没关系,一天记录一点儿,一天心情会变化一些。加油小权子!睡觉!!!那个地址偏移12,大家可以八卦一下!