C语言可变参数全解

cstdarg(stdarg.h)
可变参数的处理
    这个头文件定义了一些宏,可以通过这些宏来逐个访问被调函数的没有名字的参数列表,这些参数的个数
和类型都是不知道的。
    一个函数可以通过包含一个逗号和三个点(,...)接收可变数量的额外参数,而不需要给出相应的参数定义。
这些可变参数必须出现在常规命名参数的后面。

返回值 函数名 (参数声明 , ...);
可以通过该头文件中定义的宏va_start, va_arg和va_end来访问额外的参数。
*首先,va_start初始化了一个名为va_list的可变参数列表;
*序列的执行va_arg将会按照参数传递给函数的顺序产生额外参数的值;
*最胡,va_end必须在函数返回之前被执行。

该头文件包含了一个类型:
va_list 包含可变参数信息的类型。(类型)
三个函数:
va_start         初始化一个可变参数列表。(宏)
va_arg 获取下一个参数。                (宏)
va_end 停止使用可变参数列表。    (宏)

    一些C编译器的实现(例如ISO C99兼容的编译器)同样也包含一个va_copy宏,用于复制一个va_list对象,
但是这并不是ISO C++标准的一部分。



va_start
void va_start (va_list ap, paramN);
初始化可变参数列表
    初始化最为参数传入的va_list类型的对象ap,ap保存了通过va_arg获得参数paramN之后的可变参数的
信息。
    一个函数执行了va_start,就必须在函数返回之前执行va_end。

参数
ap
va_list类型的对象,保存了通过va_arg获取可变参数的信息。
paramN
函数定义的最后一个命名参数的名字。

返回值


示例

[cpp] view plaincopy
  1. <span style="font-size:16px;">/* va_start example */  
  2. #include <stdio.h>  
  3. #include <stdarg.h>  
  4.   
  5. void PrintFloats ( int amount, ...)  
  6. {  
  7.   int i;  
  8.   double val;  
  9.   printf ("Floats passed: ");  
  10.   va_list vl;  
  11.   va_start(vl,amount);  
  12.   for (i=0;i<amount;i++)  
  13.   {  
  14.     val=va_arg(vl,double);  
  15.     printf ("\t%.2f",val);  
  16.   }  
  17.   va_end(vl);  
  18.   printf ("\n");  
  19. }  
  20.   
  21. int main ()  
  22. {  
  23.   PrintFloats (3,3.14159,2.71828,1.41421);  
  24.   return 0;  
  25. }</span>  

这函数PrintFloats以amount作为它的第一个参数,代表额外参数的数量,将会通过cstaarg定义的宏读取,
并且以一种特殊的格式打印出来。



va_arg
type va_arg (  va_list ap, type )
获取下一个参数
    这个宏展开成了一个表达式,该表达式包含着可变参数列表中下一个参数的类型和值。
    下一次调用这个宏将会展开以同样顺序传递给函数的下一个参数。
注意va_arg不能决定传递给函数的参数的实际类型,但是可以以宏type的类型作为它的类型。
同样也需要注意va_arg不能决定此次获取的参数是否为传递给该函数的参数中的最后一个。函数必须如下
来设计:参数的数量必须可以通过已经读取的命名的或者是没命名的参数的值来确定。

参数
ap
    一个va_list类型的对象。这个参数在va_arg调用之前,必须通过调用va_start来初始化。
type
    一个类型名。这个类型名就是该宏展开后的表达式的类型(例如,它的返回类型)。一个合法的适合va_arg
使用的类型表达式必须如下:当一个*号添加到它的右边,那么它的结果表达式必须是一个合法的type类型的
指针。

返回值
以类型type的类型表达式返回下一个额外参数。


示例
[cpp] view plaincopy
  1. <span style="font-size:16px;">/* va_arg example */  
  2. #include <stdio.h>  
  3. #include <stdarg.h>  
  4.   
  5.   
  6. int FindMax ( int amount, ...)  
  7. {  
  8.   int i,val,greater;  
  9.   va_list vl;  
  10.   va_start(vl,amount);  
  11.   greater=va_arg(vl,int);  
  12.   for (i=1;i<amount;i++)  
  13.   {  
  14.     val=va_arg(vl,int);  
  15.     greater=(greater>val)?greater:val;  
  16.   }  
  17.   va_end(vl);  
  18.   return greater;  
  19. }  
  20.   
  21.   
  22. int main ()  
  23. {  
  24.   int m;  
  25.   m= FindMax (7,702,422,631,834,892,104,772);  
  26.   printf ("The greatest one is: %d\n",m);  
  27.   return 0;  
  28. }</span>  

FindMax函数使用它的第一个参数保存将会获取到的额外参数的数量。第一个额外的参数被获取并且作为初始
的比较值,然后在一个循环里获取余下的参数并且返回其中最大的一个(在这里就是892)。



va_end
void va_end( va_list ap );
    执行合适的动作,使得我们可以从使用了va_list类型对象ap获取额外参数的函数中正常返回。
    无论va_start在之前的什么时候被执行,这个宏必须在函数返回之前执行。
参数
ap
    va_list对象,也就是之前通过va_start初始化的对象。
返回值


示例

[cpp] view plaincopy
  1. <span style="font-size:16px;">/* va_arg example */  
  2. #include <stdio.h>  
  3. #include <stdarg.h>  
  4.   
  5. void PrintLines ( char* first, ...)  
  6. {  
  7.   char* str;  
  8.   va_list vl;  
  9.   
  10.   str=first;  
  11.   
  12.   va_start(vl,first);  
  13.   
  14.   do {  
  15.     printf ("%s\n",str);  
  16.     str=va_arg(vl,char*);  
  17.   } while (str!=NULL);  
  18.   
  19.   va_end(vl);  
  20. }  
  21.   
  22. int main ()  
  23. {  
  24.   PrintLines ("First","Second","Third","Fourth",NULL);  
  25.   return 0;  
  26. }</span>  

PrintLines函数使用了可变参数。第一个传递的参数是first,但是余下的参数都是在do-while循环中使用
va_arg一次获得了,该循环在获取的可变参数为null指针的时候结束。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/452116.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Diango博客--23.单元测试:测试 blog 应用

文章目录1. 前言2. 搭建测试环境3. 测试模型4. 测试视图5. 测试模板标签6. 测试辅助方法和类1. 前言 我们博客功能越来越来完善了&#xff0c;但这也带来了一个问题&#xff0c;我们不敢轻易地修改已有功能的代码了&#xff01; 我们怎么知道代码修改后带来了预期的效果&…

一般与特殊结构关系 整体与部分结构关系

一般与特殊结构关系又称为分类结构关系&#xff0c;是“is a”关系。 例如&#xff1a;飞机与交通工具都是类&#xff0c;飞机是一种特殊的交通工具。他们之间是“is a”关系。 上层类体现一般性和共性&#xff0c;下层类体现特殊性和具体性。 用这种结构关系来描述现实世界…

简单版:带干扰线的图形验证码生成

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 1.生成工具类; import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.image.BufferedImage; im…

图片格式转换工具与方法

2019独角兽企业重金招聘Python工程师标准>>> 使用ffmpeg进行格式转换 1.jpg 转 I420 ffmpeg -i 001.jpg -pix_fmt yuv420p 001_I420_fromJPG.yuv 2.png 转 I420 ffmpeg -i 222.png -pix_fmt yuv420p 222_I420_fromPNG.yuv 3.bmp 转 I420 ffmpeg -i xxx.bmp -pix_fmt…

Diango博客--24.单元测试:测试评论应用

文章目录1. 前言2. 数据基类3.测试 Comment Model4. 测试视图函数5. 测试模板标签1. 前言 comments应用的测试和blog应用测试的套路是一样的。 先来建立测试文件的目录结构。首先在 comments 应用的目录下建立一个名为 tests 的 Python 包&#xff0c;然后删除 comments 应用…

面向对象设计使用语言选择

面向对象设计的结果既可以用面向对象语言、也可以用非面向对象语言实现。 使用面向对象语言时&#xff0c;由于语言本身充分支持面向对象概念的实现&#xff0c;因此&#xff0c;编译程序可以自动把面向对象概念映射到目标程序中。 使用非面向对象语言编写面向对象程序&#xf…

结合shiro 的图形验证码生成

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 在做用户登录功能时&#xff0c;很多时候都需要验证码支持&#xff0c;验证码的目的是为了防止机器人模拟真实用户登录而恶意访问&#…

利用C语言实现计算机图像处理的方法

1&#xff0e;图像平移 图像平移只是改变图像在屏幕上的位置&#xff0c;图像本身并不发生变化。假设原图像区域左上角坐标为(x0, y0)&#xff0c;右下角坐标为(x1, y1)&#xff0c;将图像分别沿x和y轴平移dx和dy&#xff0c;则新图像的左上角坐标为(x0 &#xff0b; dx, y0 &a…

E24- please install the following Perl modules before executing ./mysql_install_db

2019独角兽企业重金招聘Python工程师标准>>> [roott-cet7 scripts]# ./mysql_install_db --basedir/usr/local/mysql/ --datadir/app/data/ --usermysql FATAL ERROR: please install the following Perl modules before executing ./mysql_install_db: Data::Dumpe…

SpringMVC异常报406 (Not Acceptable)的解决办法

使用SpsringMVC&#xff0c;使用restEasy调试&#xff0c;controller请求设置如下&#xff1a; Java代码 RequestMapping(value"/list",methodRequestMethod.GET,producesMediaType.APPLICATION_JSON_VALUE) ResponseBody public List<EditTimeout> list()…

Diango博客--25.使用Coverage统计测试覆盖率

文章目录1. 前言2. 安装 Coverage3. 简单配置 Coverage4. 运行 Coverage5. 完善 Coverage 配置6. 生成 HTML 报告7. 完善单元测试1. 前言 我们完成了对 blog 应用和 comment 应用这两个核心 app 的测试。现在我们想知道的是究竟测试效果怎么样呢&#xff1f;测试充分吗&#x…

面向对象语言的优点

1.一致的表达方法 从前面章节的讲述中可以知道&#xff0c;面向对象开发基于不随时间变化的、一致的表示方法。这种表示方法应该从问题域到OOA&#xff0c;从OOA到OOD&#xff0c;最后从OOD到面向对象编程(OOP)&#xff0c;始终稳定不变。 一致的表示方法&#xff1a; 既有利…

最好的英文词典

辞典对于学外语的作用&#xff0c;怎么强调也不过分。经常接触英语的人都知道&#xff0c;遇到生词不可怕&#xff0c;可怕的是遇到认识的单词&#xff0c;又不明白这句话什么意思。这个时候&#xff0c;辞典的作用就发挥出来了。 今天一位朋友问我一句英文的意思&#xff0c;…

oracle用户创建及权限设置

权限&#xff1a; create session create table unlimited tablespace connect resource dba 例&#xff1a; #sqlplus /nolog SQL> conn / as sysdba; SQL>create user username identified by password SQL> grant dba to username; SQL> conn username/password…

Android动画之逐帧动画(FrameAnimation)详解

今天我们就来学习逐帧动画,废话少说直接上效果图如下: 帧动画的实现方式有两种&#xff1a; 一、在res/drawable文件夹下新建animation-list的XML实现帧动画 1、首先在res/drawable文件夹下添加img00-img24共25张图片 2、新建frame_anim.xml [html] view plaincopy <?xml v…

ajax-简单参数方法实现阴影效果

注&#xff1a; 简单参数 &#xff08;按照参数的数量和位置传递参数&#xff09; 使用时按照位置、数量传递 shadow.js函数//简单参数实现方式/** slices:阴影* opacity:透明度* zIndex:层级* */jQuery.fn.shadow_simple function (slices,opacity,zIndex) { //获取到每个…

第一二三范式的简单理解

第一范式&#xff08;无重复的列&#xff09; 定义&#xff1a;数据库表的每一列都是不可分割的原子数据项&#xff0c;而不能是集合&#xff0c;数组&#xff0c;记录等非原子数据项。如果实体中的某个属性有多个值时&#xff0c;必须拆分为不同的属性 通俗解释&#xff1a;一…

网络爬虫--1.通用爬虫和聚焦爬虫

文章目录一.前言二.通用爬虫1.工作原理2.通用爬虫的局限性三.聚焦爬虫一.前言 根据使用场景&#xff0c;网络爬虫可分为 通用爬虫 和 聚焦爬虫 两种。 其中通用网络爬虫是捜索引擎抓取系统&#xff08;Baidu、Google、Yahoo等&#xff09;的重要组成部分。主要目的是将互联网…

敏捷教练的工具箱

学习并不是简简单单的阅读和浏览&#xff0c;而是一个积累的过程&#xff0c;一个通过持续的学习&#xff0c;对自己的知识体系不断丰富、索引的过程。接下来我会从四个方面入手分享我的经验。 高质量的信息源和高效的学习 Google是一个很好的工具&#xff0c;通过它&#x…

log4j教程

详细的Log4j使用教程 转载 2016年08月19日 14:44:49 5072 日志是应用软件中不可缺少的部分&#xff0c;Apache的开源项目log4j是一个功能强大的日志组件,提供方便的日志记录。在apache网站&#xff1a;jakarta.apache.org/log4j 可以免费下载到Log4j最新版本的软件包。…