va_start、va_arg、va_end、va_copy 可变参函数
1、应用与原理
int printf(const char *format, ...);
int fprintf(FILE *stream, const char *format, ...);
2、va_start、va_arg、va_end、va_copy介绍
#include <stdarg.h>
void va_start(va_list ap, last);
type va_arg(va_list ap, type);
void va_end(va_list ap);
void va_copy(va_list dest, va_list src);
typedef struct {
char *a0; /* pointer to first homed integer argument */
int offset; /* byte offset of next parameter */
} va_list;
*fmt, ...) 中的fmt。通过va_start初始化ap,我们就获得了可变参数前一个参数fmt的地址。
3、Example
//foo.c
#include <stdarg.h>
#include <stdio.h>
void
foo(char *fmt, ...)
{
va_list ap;
int d;
char c, *s;
va_start(ap, fmt);
while (*fmt)
switch (*fmt++) {
case 's': /* string */
s = va_arg(ap, char *);
printf("string %s\n", s);
break;
case 'd': /* int */
d = va_arg(ap, int);
printf("int %d\n", d);
break;
case 'c': /* char */
/* need a cast here since va_arg only
/* need a cast here since va_arg only
takes fully promoted types */
c = (char) va_arg(ap, int);
printf("char %c\n", c);
break;
}
va_end(ap);
}
//main.c
#include <stdio.h>
#include <stdarg.h>
#include "foo.h"
int
main(void)
{
foo("%s %d %c %d %c", "Hello", 4, 'x', 3, 'y');
return 0;
}
windeal@ubuntu:~/Windeal/apue$ ./exe
string Hello
int 4
char x
int 3
char y
windeal@ubuntu:~/Windeal/apue$
//foo.c
#include <stdarg.h>
#include <stdio.h>
void
foo(char *fmt, ...)
{
va_list ap;
int len = 0;
char buf[64];
va_start(ap, fmt);
len = vsnprintf(buf, 128, fmt, ap);
va_end(ap);
int i = 0;
for(i = 0; i < len; i++)
{
putchar(buf[i]);
}
return ;
}
// main.c
#include <stdio.h>
#include <stdarg.h>
#include "foo.h"
int
main(void)
{
foo("Test:%s %d %c %d %c\n", "Hello", 4, 'x', 3, 'y');
return 0;
}
windeal@ubuntu:~/Windeal/apue$ ./exe
Test:Hello 4 x 3 y
va_start、va_arg、va_end、va_copy 可变参函数va_start、va_arg、va_end、va_copy 可变参函数
va_start、va_arg、va_end、va_copy 可变参函数的更多相关文章
- va_start,va_arg,va_end的使用
一.在C中,当我们无法列出传递函数的所有实参的类型和数目时,可以用省略号指定参数表. void fun(...); void fun(parm_list,...); #include <stdi ...
- va_list/va_start/va_arg/va_end深入分析【转】
转自:http://www.cnblogs.com/justinzhang/archive/2011/09/29/2195969.html va_list/va_start/va_arg/va_end ...
- C++省略参数(va_list va_start va_arg va_end)的简单应用
原文参考自:http://www.cnblogs.com/hanyonglu/archive/2011/05/07/2039916.html #include <iostream> #in ...
- va_list/va_start/va_arg/va_end深入分析
http://www.cnblogs.com/justinzhang/archive/2011/09/29/2195969.html
- va_start(),va_end()函数应用【转】
转自:http://www.cnblogs.com/gogly/articles/2416833.html 原理解释: VA_LIST 是在C语言中解决变参问题的一组宏,在<stdarg.h&g ...
- va_start(),va_end()函数应用
原理解释: VA_LIST 是在C语言中解决变参问题的一组宏,在<stdarg.h>头文件下. VA_LIST的用法: (1)首先在函数里定义一具VA_LIST型的变 ...
- va_list、va_start和va_end使用
我们知道va_start,va_arg,va_end是在stdarg.h中被定义成宏的,由于1.硬件平台的不同 2.编译器的不同,所以定义的宏也有所不同. 在ANSI C中,这些宏的定义位于stdar ...
- va_start和va_end使用详解
本文主要介绍va_start和va_end的使用及原理. 介绍这两个宏之前先看一下C中传递函数的参数时的用法和原理: 1.在C中,当我们无法列出传递函数的所有实参的类型和数目时,可以用省略号指定参数表 ...
- [转载]va_start和va_end使用详解
va_start和va_end使用详解 原文地址:http://www.cnblogs.com/hanyonglu/archive/2011/05/07/2039916.html 本文主要介绍va_s ...
随机推荐
- yum安装redis phpredis扩展
转载地址:http://blog.csdn.net/musicrabbit/article/details/9729941 redis和php-redis在官方源上是没有的,需要安装其他的源,其他源的 ...
- ionic android - Unable to start the daemon process. Could not reserve enough space for 2097152KB object heap
Unzipping C:\Users\app\.gradle\wrapper\dists\gradle-4.1-all\bzyivzo6n839fup2jbap0tjew\gradle-4.1-all ...
- MR案例:定制Partitioner
可以继承基类Partitioner,也可以继承默认的HashPartitioner类,覆写其中的 getPartition() 方法实现自己的分区. 需求:本例是对上一个实例的改写,需求不变 pack ...
- c语言数组拷贝
#include <string.h> // 如果要从数组a复制k个元素到数组b,可以这样做 memcpy(b,a,sizeof(int)*k);
- 采用OpenReplicator解析MySQL binlog
Open Replicator是一个用Java编写的MySQL binlog分析程序.Open Replicator 首先连接到MySQL(就像一个普通的MySQL Slave一样),然后接收和分析b ...
- java 反序列化 漏洞
java在反序列化的时候会默认调用被重写的readObject(ObjectInputStream )方法. 在远程服务端一个需要反序列化的接口中,比如一个web服务,他那个接口调用链中有反序 ...
- python的变量,对象的内存地址以及参数传递过程
作为一个由c/c++转过来的菜鸟,刚接触Python的变量的时候很不适应,应为他的行为很像指针,void* ,不知道大家有没有这样的感觉.其实Python是以数据为本,变量可以理解为标签.作为c/c+ ...
- Android自定义view-CircleSeekbar
自定义view练手,效果图如下:实现功能 可设置圆环颜色和线宽及触摸后的颜色和线宽 可设置圆环内圈显示的文本内容及字体大小.颜色 可设置触摸点的图片 可设置触摸的有效范围 源码git ...
- spark streaming之 windowDuration、slideDuration、batchDuration
spark streaming 不同于sotm,是一种准实时处理系统.storm 中,把批处理看错是时间教程的实时处理.而在spark streaming中,则反过来,把实时处理看作为时间极小的批处理 ...
- [myeclipse]@override报错问题
@Override是JDK5 就已经有了,但有个小小的Bug,就是不支持对接口的实现,认为这不是Override 而JDK6 修正了这个Bug,无论是对父类的方法覆盖还是对接口的实现都可以加上@Ove ...