当前位置: 首页 > news >正文

大连网站开发价格/百度小程序入口

大连网站开发价格,百度小程序入口,网站建设公司郴州,郑州网站建设公司招聘我们用的最多的C函数是哪个?毫无疑问,是printf。但是你看过printf的声明式吗,那是相当诡异。随便拿一本带C库函数参考的书,可查到如下结果:int printf(const char *format, ...);那三个连续的点就代表大于或等于0个参数…
我们用的最多的C函数是哪个?毫无疑问,是printf。但是你看过printf的声明式吗,那是相当诡异。随便拿一本带C库函数参考的书,可查到如下结果:
             int printf(const char *format, ...);
那三个连续的点就代表大于或等于0个参数,再加上前面的format参数,所以printf函数至少要接受一个字符串,后面就随便了。但是这是如何实现的呢,不急,首先必须要了解C语言函数参数传递的机制。

C语言函数参数传递机制

我们知道,每个程序都有个用户栈,所有的函数调用都要使用它,比如被调用函数的实参及局部变量都要存在用户栈中,所以每个函数都有个栈帧。下面我用两个函数来说明这种调用机制:
int main(void)                             int add(int param1, int param2)
{                                          {
    int a, b, c;                               int d;
    a = 2;                                     d = param1 + param2;
    b = 3;                                     return param1+param2;
    c = add(a,b);                          }
    return 0;

}
main函数在调用add函数时,main负责把b,a及eip(即返回地址)按顺序压栈,注意栈是向下增长的。然后执行call指令调用add函数。(ps: 其实在返回地址和局部变量d之间函数add还会压入一些寄存器,但是这对我们理解变长参数没有影响,总之要记住参数是自右向左压栈的)
                              

处理变长参数的宏定义
处理变长参数说白了就是怎样获取那些在声明中没明说的参数,比如在printf("%d equals to %d.", a, b)中,第一个字符串参数可直接通过format取得,但a和b呢?这就要需要对参数传递的理解了。主函数调用printf时肯定是先压入b,再压入a,最后压入"%d equals to %d"的地址。
现在我们来获取a的地址,很简单,当然是 (char*)&format+sizeof(const char*)。其中&format是参数format在栈中的地址,而a正好format上面。

OK, 现在我们可以系统地讲解处理变长参数的宏了。
在头文件stdarg.h中先定义个类型 va_list,它是专门用来去可变参数的,如果要对付可变参数首先要定义一个va_list类型的变量ap:
            typedef char* va_list;
因为在获取参数地址时必须知道它前一个参数的数据类型大小,所以要定义__va_sizeof(type),它的作用和sizeof一样,不过__va_sizeof(char),__va_sizeof(short)的值都是4:
            #define __va_sizeof(type) (((sizeof(type) + sizeof(int) - 1) / sizeof(int)) * sizeof(int))      
然后定义va_start获取第一个可变参数的地址:
            #define va_start(ap, last) ((ap) = (va_list)&(last) + __va_size(last))
va_arg用于获取ap当前指向的参数的值,并顺带把va_list移向下一个参数
            #define va_arg(ap, type) (*(type *)((ap) += __va_size(type), (ap) - __va_size(type)))
当用完ap时,用va_end将其赋值为空,也就是0
            #define va_end(ap) (ap)=0


处理变长参数的一般框架
如果我们自己实现printf函数,代码的形式大概如下
int chparamf(const char *format, ...)
{
    va_list ap;
    va_start(ap,format);
    循环使用 va_arg(ap,你要取的参数的数据类型)
    va_end(ap);
}

转载于:https://www.cnblogs.com/john-d/archive/2009/11/08/1598440.html

http://www.lbrq.cn/news/737515.html

相关文章:

  • 海淀区网站建设/百度账号批发网
  • 棋类游戏网站开发/西安seo服务公司排名
  • 用记事本做电影介绍的网站/黑帽seo优化
  • 南京做网站建设有哪些/游戏推广怎么做引流
  • e站注册网站/餐饮营销策划方案
  • 网站建设 后台/企业网络宣传推广方案
  • 天津市建设工程造价管理协会网站/市场营销案例
  • java做的网站用什么发布/昆山网站制作公司
  • 南通购物网站建设/seo网站是什么意思
  • p2p网上贷款网站建设方案/seo入门培训学校
  • 怎样申请免费网站域名/广州网站建设方案优化
  • 电商网站开发计划书/百度拍照搜索
  • 动态网站和静态网站/点击排名优化
  • 家具网站建设规划书/清博舆情系统
  • 静态手机网站/百度推广开户公司
  • 上海网站开发薪资/上海做网站优化
  • ionic3 做网站/企业文化建设
  • 行业门户网站设计/百度服务电话
  • 网站死链接怎么删除/新闻热点事件2021(最新)
  • 网络服务提供者是不是网络运营者/北京网站优化服务商
  • 最好企业网站/google play下载
  • 可信赖的扬中网站建设/媒体网络推广价格优惠
  • 企业黄页88网/seo网站优化软件价格
  • 做网站电话销售/深圳企业黄页网
  • 广州海珠区景点排行榜前十名/seo快速排名服务
  • 国外网站建设费用/阿里指数查询官网
  • 江阴网站制作设计/百度怎么搜索关键词
  • html5 网站开发 适配/谷歌搜索引擎镜像入口
  • 青海建筑网站建设公司/代写文章兼职
  • 美食网站中饮食资讯该怎么做/百度seo收录软件
  • 49 C++ STL模板库18-类模板-pair
  • 【数据结构】递归与非递归:归并排序全解析
  • HTML5 视频与音频完全指南:从基础的 <video> / <audio> 标签到现代 Web 媒体应用
  • 实验8.20
  • TDengine IDMP 运维指南(4. 使用 Docker 部署)
  • 走进数字时代,融入数字生活,构建数字生态