遵义网站开发,如何设置网站名字吗,页面设计素材,wordpress 中文图片不显示相信大家都使用过C语言的库函数#xff1a;printf(%d%d, 1, 2)的吧#xff0c;使用确实很方便功能也很强大。 但是为什么它可以接受多个参数呢#xff1f; 现在我们来解析一下多参的实现原理#xff0c;网上也找了一些文章。发现解析得都不全面。并且有BUG。 先…相信大家都使用过C语言的库函数printf(%d%d, 1, 2)的吧使用确实很方便功能也很强大。 但是为什么它可以接受多个参数呢 现在我们来解析一下多参的实现原理网上也找了一些文章。发现解析得都不全面。并且有BUG。 先看如下源码 #include windows.h
#include stdio.h
#include winnt.hvoid MySprintf(char* szBuffer, const char* szFormat, ...)
{va_list pa; // 定义一个指针va_start(pa, szFormat); // 把指针赋值为第一个参数的值vsprintf(szBuffer, szFormat, pa);// va_end(pa); // 清空
}
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,PSTR szCmdLine, int iCmdShow)
{char szBuffer[128] {0};MySprintf(szBuffer, %d%d%d, 1,2,3);return 0 ;
} 首先我们函数压参顺序是重右往左对应的栈空间内存地址从高到低。 MySprintf(szBuffer, %d%d%d, 1,2,3); 这行代码分别想栈中压入3, 2, 1, 然后再是szFormat的内存空间,在是szBuffer的内存空间. 内存结构如下 熟悉函数调用的几步过程,压入参数,保存返回地址和栈顶,开辟局部变量空间. 现在保存了返回地址然后继续执行的话就是保存栈顶和开辟va_list pa所需的内存空间. va_list其实也就是char* 类型。占4个字节。继续执行后如下 看到了吗va_start(pa, szFormat); 这条语句计算出了参数的起始地址 它是如何计算出的呢我们既然知道了内存布局, 那szFormat取地址sizeof(va_list)。 说简单点也就是szFormat的内存地址 4个字节. 不就刚好偏移到第一个参数的地址处了吗 并且 以上的MySprintf函数等同于下面这种写法 void MySprintf(char* szBuffer, const char* szFormat, ...)
{char* pCh NULL;pCh (char*)szFormat sizeof(pCh);vsprintf(szBuffer, szFormat, pCh);pCh NULL;
} 现在,我们得到了参数的内存首地址但是还缺少信息。缺什么信息 当前地址处有几个参数每个参数什么类型占用字节数 关键的地方就在这里了。szFormat中有类型信息信息并且有类型信息的个数我们可以通过遍历字符串 找出类型信息的顺序和个数。然后根据遍历找到的信息。来解析参数的内存首地址。 具体的做法.在vsprintf中有实现,下面是拷贝vsprintf的实现代码 #ifndef _COUNT_int __cdecl vsprintf (char *string,const char *format,va_list ap)
#else /* _COUNT_ */int __cdecl _vsnprintf (char *string,size_t count,const char *format,va_list ap)
#endif /* _COUNT_ */{FILE str;REG1 FILE *outfile str;REG2 int retval;_ASSERTE(string ! NULL);_ASSERTE(format ! NULL);outfile-_flag _IOWRT|_IOSTRG;outfile-_ptr outfile-_base string;
#ifndef _COUNT_outfile-_cnt MAXSTR;
#else /* _COUNT_ */outfile-_cnt count;
#endif /* _COUNT_ *//*简单说明:关键代码处大家直接跟进去即可,先是做些判断然后设置一些标志位最后把数字根据设置的标志转为字符串.*/retval _output(outfile,format,ap );_putc_lk(\0,outfile);return(retval);
} 本人菜鸟水平有限望各路大牛指点!转载于:https://www.cnblogs.com/ziolo/archive/2013/04/22/3036346.html