next用法C语言,C语言可变参数的使用
先来个简单的例子:#include
#include
void test0(int num,...)
{
va_list ap;
va_start(ap, num);
while(num--)
{
printf("%s ",va_arg(ap, char *));
}
va_end(ap);
}
void test1(int num,...)
{
va_list ap;
va_start(ap, num);
while(num--)
{
printf("%d ",va_arg(ap, int *));//为什么输出正确结果呢??
}
va_end(ap);
printf("\n");
}
void test2(int num,...)
{
va_list ap;
va_start(ap, num);
while(num--)
{
printf("%d ",va_arg(ap, int));
}
va_end(ap);
printf("\n");
}
void test3(int num,...)
{
va_list ap;
va_start(ap, num);
while(num--)
{
printf("%c ",va_arg(ap, char));
}
va_end(ap);
printf("\n");
}
int main()
{
test0(3, "hello", "world", "!\n");
test1(4, 1, 2, 3 ,4);
test2(2, 1, 2, 3 ,4);
test2(3, '1', '2', '3' ,'4');
return 0;
}
输出:
hello world !
1 2 3 4
1 2
49 50 51//为什么不能输出1 2 3??
可变参数中个数不定可是传入的是一个参数也可以是多个;可变参数中的每个参数的类型可以不同,也可以相同;可变参数的每个参数并没有实际的名称与之相对应,用起来是很灵活。可变参数是由宏实现的,但是由于硬件平台的不同,编译器的不同,宏的定义也不相同,下面是VC6.0中x86平台的定义:
typedef char * va_list; // TC中定义为void*
#define _INTSIZEOF(n)
((sizeof(n)+sizeof(int)-1)&~(sizeof(int) - 1) ) //为了满足需要内存对齐的系统,求int型大小#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 ) t为变量类型
C语言的函数形参是从右向左压入堆栈的,以保证栈顶是第一个参数,而且x86平台内存分配顺序是从高地址到低地址。因此似函数fun(int var1,int var2,...,int varN)内存分配大致上是这样的:(可变参数在中间)栈区:
|栈顶低地址|第一个参数var1 |第二个参数var2 后ap指向地址|...
|函数的最后varN
|...
|函数的返回地址|...
|栈底高地址va_start(ap,v);后ap = (va_list)&v + _INTSIZEOF(v)指向第二个参数地址调用va_arg(ap,t) ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )取出当前ap指针所指的值,并使ap指向下一个参数
不过被定义为宏的东西用起来要小心,我现在用不着va_list,不过先了解点皮毛也好。
下面是msdn中的例子: beautiful
#include
#define ANSI/* Comment out for UNIX version*/
#ifdef ANSI/* ANSI compatible version*/
#include
int average( int first, ... );
#else/* UNIX compatible version*/
#include
int average( va_list );
#endif
void main( void )
{
/* Call with 3 integers (-1 is used as terminator). */
printf( "Average is: %d\n", average( 2, 3, 4, -1 ) );
/* Call with 4 integers. */
printf( "Average is: %d\n", average( 5, 7, 9, 11, -1 ) );
/* Call with just -1 terminator. */
printf( "Average is: %d\n", average( -1 ) );
}
/* Returns the average of a variable list of integers. */
#ifdef ANSI/* ANSI compatible version*/
int average( int first, ... )
{
int count = 0, sum = 0, i = first;
va_list marker;
va_start( marker, first );/* Initialize variable arguments. */
while( i != -1 )
{
sum += i;
count++;
printf(" %d sum: %d", i, sum);
i = va_arg( marker, int);
}
va_end( marker );/* Reset variable arguments.*/
return( sum ? (sum / count) : 0 );
}
#else/* UNIX compatible version must use old-style definition.*/
int average( va_alist )
va_dcl
{
int i, count, sum;
va_list marker;
va_start( marker );/* Initialize variable arguments. */
for( sum = count = 0; (i = va_arg( marker, int)) != -1; count++ )
sum += i;
va_end( marker );/* Reset variable arguments.*/
return( sum ? (sum / count) : 0 );
}
#endif
结果:
2 sum: 2 3 sum: 5 4 sum: 9Average is: 3
5 sum: 5 7 sum: 12 9 sum: 21 11 sum: 32Average is: 8
Average is: 0
Press any key to continue
在来一个简单的例子:#include #include
void print(char *format,...); //自定义输出格式void print(char *format,...)
{
va_list argptr;
va_start(argptr, format);
while(*format != '\0')
{
switch(*(format++))
{
case 's': printf("%s ", va_arg(argptr, char *)); break;
case 'i': printf("%d ", va_arg(argptr, int)); break;
case 'c': printf("%c ", va_arg(argptr, char)); break;
case 'f': printf("%.1f\n", va_arg(argptr, double)); break;
default: break;
}
}
va_end(argptr);
}
int main()
{
print("sicft","laomou",24,'M',120.0); //输出格式依次为string, integer, char, float
return 0;
}
next用法C语言,C语言可变参数的使用相关推荐
- c语言理解参数,c语言中对可变参数列表的简单理解
函数原型中一般情况下参数的数目是固定的,但是如果想在不同的时候接收不定数目的参数时该怎么办呢?c语言提供了可变参数列表来实现. 可变参数列表是通过宏来实现的,这些宏定义在stdarg.h的头文件中.头 ...
- C语言中函数可变参数解析
大多数时候,函数中形式参数的数目通常是确定的,在调用时要依次给出与形式参数对应的所有实际参数.但在某些情况下希望函数的参数个数可以根据需要确定.典型的例子有 大家熟悉的函数printf().scanf ...
- 编写可变参数函数 c语言,C语言中编写可变参数函数
通过stdarg.h头文件为函数提供了定义可变参数列表的能力.声明一个可变参数的函数类似: void f1(int n,...); 其中n表示参数列表个数,而用省略号来表示未知参数列表.stdarg. ...
- 【转载】c语言中的可变参数编程
在c语言中使用变长参数最常见的就是下面两个函数了: int printf(const char *format, ...);int scanf(const char *format, ...); 那他 ...
- 【嵌入式】C语言高级编程-可变参数宏(12)
00. 目录 文章目录 00. 目录 01. 可变参数宏概述 02. ##符号 03. 可变参宏另外一种写法 04. 内核中的可变参数宏 05. 附录 01. 可变参数宏概述 #include < ...
- 【C/C++开发】C语言实现函数可变参数
函数原型: int printf(const char *format[,argument]...) 返 回 值: 成功则返回实际输出的字符数,失败返回-1. 函数说明: ...
- 【C语言进阶深度学习记录】三十九 C语言中的可变参数(参数可变的函数)
用过printf()函数的热都知道,printf的参数可以有多个,它是可变的,根据我们输出参数的类型以及个数的不同来确定参数.今天来学习C语言中参数可变的函数是如何实现的. 文章目录 1 可变参数 2 ...
- C语言学习笔记---可变参数
在C语言中有些函数传递进入的参数数量是不固定的,最常见的就是 printf() 函数,它就是利用可变参数来实现任意格式的数据打印功能. 我们自己也可以编写一个参数可变的函数,每次动态的检测传入的参 ...
- c语言va_start函数,va_start和va_end,以及c语言中的可变参数原理
FROM:http://www.cnblogs.com/hanyonglu/archive/2011/05/07/2039916.html 本文主要介绍va_start和va_end的使用及原理. 在 ...
- C语言_函数可变参数列表
函数可变参数列表的应用和原理 在网上看到各位前辈关于这部分的介绍有些是过于简洁,有些则是过于晦涩,有的代码拿出来甚至在编译器上跑不过去,所以在这里讲一下自己对于可变参数的认识,若有不正确的地方,欢迎各 ...
最新文章
- 开源吞噬世界,得开发者得天下
- Explore the Service Console
- springboot 各种日志打印
- Mysql的安装和配置
- flutter向上动画弹出菜单效果
- 计算机网络课设telnet_【川大】计算机网络课程设计9013,奥鹏2017
- 升哲科技 x 百度智能云丨智能全感知系统,挽救 127 个生命的城市安全方案
- Java中线程安全的单例模式
- 谈谈流计算中的『Exactly Once』特性
- linux小红帽网卡设定,LINUX红帽子怎么配置上网
- 整数规划:分支定界法
- oppo9s刷机教程_OPPOR9SPlus官方固件刷机教程_线刷|救砖教程图解
- 计算机u盘读不出来,详细教你解决电脑读不出u盘
- [论文笔记]Fader Networks: Manipulating Images by Sliding Attributes(2017 NIPS)
- 实时文件同步工具-端端Clouduolc在项目研发中的使用体会
- 关于微信第三方平台$APPID$.wx.abc.com的问题
- C语言指针-什么是指针,如何引用指针
- zxl-机器学习-01
- 61、智能指针类模板
- java用hutool.excelUtil实现excel创建模板和下载模板
热门文章
- SLF4J 之logback.xml配置文件实例及其说明
- Python核心模块——urllib模块
- 基于easyui开发Web版Activiti流程定制器详解(五)——Draw2d详解(一)
- Oracle查看SQL执行计划的方式
- 大白话系列之C#委托与事件讲解(一)
- MySQL主从复制配置过程(一主一从模式)
- GIT之git及git服务搭建
- 华为某研究生程序员哀叹:年薪五十多万,存款一百万,却不知道未来怎么走!...
- vivo统一告警平台建设与实践
- 头条一面:Spring IOC容器中只存放单例Bean吗?