博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
编程基础知识学习———C语言中可变参数的用法
阅读量:5742 次
发布时间:2019-06-18

本文共 1753 字,大约阅读时间需要 5 分钟。

        作为一名半路杀出来的程序猿,没有经过完整流程的系统性学习,说起来有点惭愧。所以只有默默得加把劲,自己多学点东西。在工作中遇到了不懂的地方,就赶紧的查,赶紧的记下来,将知识慢慢补足。

        在项目代码中看到了va_list类型的参数,头一次看,尼玛不懂啊,赶紧Google了:

        参数个数可变的函数形式:就是在函数形参表里面没有具体写出参数的个数,而是以省略号代之,就是个数省略XX的吧。如C中的printf函数定义:

int printf( const char* format, ...);

在形参表中,只有固定的一个format参数,其后用了一个省略号代替了。这样我们在使用的时候可以传一个参数,也可以传多个参数了,如:

printf("%d",i); printf("%s",s); printf("%d ,%s", i, s);

形式上大概就是这个意思。然后回到之前的那个va_list类型来

        看了源码后,可以看到以下几个宏:

#define va_start(ap,v) ( ap = (va_list)&v + _INTSIZEOF(v) )           //第一个可选参数地址#define va_arg(ap,t) ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) ) //下一个参数地址#define va_end(ap)    ( ap = (va_list)0 )                            // 将指针置为无效
va的意思即指:variable-argument(可变参数)。然后我可耻的摘抄了一段别人的博客内容:

        具体用项目的代码说说事吧,做的是一个cocos2dx的项目,项目用的是C++。引擎的源码就用到了,比如说menuitem的创建。假设我要创建可变数量个的menuitem,我不知道要创建几个,因此我创建的时候参数个数只有一个固定参数,后接一个省略号,如:

vaMenu* vaMenuItems(CCMenuItem* item,...);
        1.在函数体内定义一个va_list型的变量:

va_list args;
        2.就要初始化这个变量了,初始化变量用到了前面提到的三个宏之一的va_start:

va_start(args,item);
这个宏有两个参数,第一个就是前面定义的va_list型变量,后面的那个变量是函数形参表中的第一个参数,即那个固定参数item,也可以说是第一个可变参数前面的那个固定参数。

ps.这个类型在引擎中是这样定义的:

#ifndef _VA_LIST#define _VA_LIST/* DO NOT REMOVE THIS COMMENT: fixincludes needs to see: * __gnuc_va_list and include 
*/typedef __darwin_va_list va_list;#endif
我知识储备不行,表示在这里不明觉厉。。。。

        3.初始化了变量args后,就到了使用这个参数的阶段了,这里使用到了前面三个宏中的第二个va_arg。使用就是利用这个参数返回可变的参数,返回类型是第二步中的那个固定参数类型,第二步的那个固定参数是一个CCMenuItem类型的指针,因此使用args返回可变参数的时候,类型会是CCMenuItem类型的指针。

CCMenuItem *i = va_arg(args, CCMenuItem*);
宏参数有两个,第一个是在函数体中定义的那个va_list变量,第二个参数表示的是返回值类型(这个类型应该必须跟初始化时使用到的那个类型一致吧?)

        4.最后用va_end宏结束可变参数的获取。

va_end(args);
应该以上四个步骤是必须的吧,缺一不可的样子。
        在不同的平台上va_list的类型会不同,三个宏的定义也会有差异,所以在实际的使用过程中会有所出入,但是在网上查阅相关的资料来看,大致的使用步骤都差不多。嗯,又学到一些东西了。

转载于:https://www.cnblogs.com/zhong-dev/p/4044599.html

你可能感兴趣的文章
怎么用sysLinux做U盘双PE+DOS??
查看>>
Spring Transactional
查看>>
shell脚本实例
查看>>
我的友情链接
查看>>
Windows Phone 7 隔离存储空间资源管理器
查看>>
Microsoft Excel 2000/2003修复工具
查看>>
apache安装报错undefined reference ssl
查看>>
关于爱情只有一句忠告
查看>>
CentOS 7下安装部署Oracle11g图文教程
查看>>
F#初学笔记06
查看>>
实战:将企业域名解析委派给企业DNS服务器
查看>>
在Lync 2013环境部署Office Web Apps
查看>>
微软大会Ignite,你准备好了么?
查看>>
读书笔记-高标管事 低调管人
查看>>
Master带给世界的思考:是“失控”还是进化
查看>>
用户和开发者不满苹果iCloud问题多多
查看>>
attrs.xml中declare-styleable 详解(用于自定义控件的属性)
查看>>
java.lang.UnsatisfiedLinkError:no dll in java.library.path终极解决之道
查看>>
我的工具:文本转音频文件
查看>>
【许晓笛】从零开始运行EOS系统
查看>>