c语言——可变参数
2017-05-29 21:49
176 查看
版权声明:原创不易,转载请注明出处:http://blog.csdn.net/wqx521
C语言——可变参数
宗旨:技术的学习是有限的,分享的精神是无限的。
1、目前为止,见过比较熟悉的可变参数的函数就是printf()函数
[cpp] view
plain copy
print?
int printf(const char *format, …);<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);"> </span>
2、可变参数宏
[cpp] view
plain copy
print?
void va_start(va_list arg_ptr, prev_param);
type va_arg(va_list arg_ptr, type);
void va_end(va_list arg_ptr);
va_list:用来保存宏va_start、va_arg和va_end所需信息的一种类型。为了访问变长参数列表中的参数,必须声明va_list类型的一个对象 定义: typedef char * va_list;
va_start:访问变长参数列表中的参数之前使用的宏,它初始化用va_list声明的对象,初始化结果供宏va_arg和va_end使用;
va_arg: 展开成一个表达式的宏,该表达式具有变长参数列表中下一个参数的值和类型。每次调用va_arg都会修改用va_list声明的对象,从而使该对象指向参数列表中的下一个参数;
va_end:该宏使程序能够从变长参数列表用宏va_start引用的函数中正常返回。
C语言内存管理中,我们提到函数的参数存放在栈中。通过反汇编可知,可变参数是从右向左依次压栈的,所以第一个参数靠近栈顶,最后一个参数靠近栈底。这些参数在内存中是连续存放的,每个参数都4字节对齐。
3、stdarg.h的一种实现
[cpp] view
plain copy
print?
/* stdarg.h standard header */
#ifndef _STDARG
#define _STDARG
/* type definitions */
typedef char *va_list;
/* macros */
#define va_arg(ap, T) \
(* (T *)(((ap) += _Bnd(T, 3U)) - _Bnd(T, 3U)))
#define va_end(ap) (void)0
#define va_start(ap, A) \
(void)((ap) = (char *)&(A) + _Bnd(A, 3U))
#define _Bnd(X, bnd) (sizeof (X) + (bnd) & ~(bnd))
#endif /*<span style="font-family: Arial, Helvetica, sans-serif;">_STDARG</span> */
这个头文件中的内部宏定义将类型或变量的长度对齐到字节的整数倍,例如_Bnd(char, 3U)的值是4,_Bnd(int,
3U)也是4
4、可变参数函数实现思路
(1)首先在函数里定义一个va_list型的变量,这里是arg_ptr,这个变 量是指向参数的指针。
(2)然后用va_start宏初始化变量arg_ptr,这个宏的第二个参数是第 一个可变参数的前一个参数,是一个固定的参数。
(3)然后用va_arg返回可变的参数,并赋值给整数j. va_arg的第二个参数是你要返回的参数的类型,这里是int型。
(4)最后用va_end宏结束可变参数的获取.然后你就可以在函数里使 用第二个参数了.如果函数有多个可变参数的,依次调用va_arg获 取各个参数。
5、myprintf函数实现
[cpp] view
plain copy
print?
#include <stdio.h>
#include <stdarg.h>
void myprintf(const char *format, ...)
{
va_list ap;
char c;
va_start(ap, format);
while(c = *format++)
{
switch(c)
{
case 'c':
{
char ch = va_arg(ap, int);
putchar(ch);
break;
}
case 's':
{
char *p = va_arg(ap, char *);
fputs(p, stdout);
break;
}
default:
putchar(c);
}
}
va_end(ap);
}
int main(void)
{
myprintf("c\ts\n", '1', "hello");
return 0;
}
C语言——可变参数
宗旨:技术的学习是有限的,分享的精神是无限的。
1、目前为止,见过比较熟悉的可变参数的函数就是printf()函数
[cpp] view
plain copy
print?
int printf(const char *format, …);<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);"> </span>
2、可变参数宏
[cpp] view
plain copy
print?
void va_start(va_list arg_ptr, prev_param);
type va_arg(va_list arg_ptr, type);
void va_end(va_list arg_ptr);
va_list:用来保存宏va_start、va_arg和va_end所需信息的一种类型。为了访问变长参数列表中的参数,必须声明va_list类型的一个对象 定义: typedef char * va_list;
va_start:访问变长参数列表中的参数之前使用的宏,它初始化用va_list声明的对象,初始化结果供宏va_arg和va_end使用;
va_arg: 展开成一个表达式的宏,该表达式具有变长参数列表中下一个参数的值和类型。每次调用va_arg都会修改用va_list声明的对象,从而使该对象指向参数列表中的下一个参数;
va_end:该宏使程序能够从变长参数列表用宏va_start引用的函数中正常返回。
C语言内存管理中,我们提到函数的参数存放在栈中。通过反汇编可知,可变参数是从右向左依次压栈的,所以第一个参数靠近栈顶,最后一个参数靠近栈底。这些参数在内存中是连续存放的,每个参数都4字节对齐。
3、stdarg.h的一种实现
[cpp] view
plain copy
print?
/* stdarg.h standard header */
#ifndef _STDARG
#define _STDARG
/* type definitions */
typedef char *va_list;
/* macros */
#define va_arg(ap, T) \
(* (T *)(((ap) += _Bnd(T, 3U)) - _Bnd(T, 3U)))
#define va_end(ap) (void)0
#define va_start(ap, A) \
(void)((ap) = (char *)&(A) + _Bnd(A, 3U))
#define _Bnd(X, bnd) (sizeof (X) + (bnd) & ~(bnd))
#endif /*<span style="font-family: Arial, Helvetica, sans-serif;">_STDARG</span> */
这个头文件中的内部宏定义将类型或变量的长度对齐到字节的整数倍,例如_Bnd(char, 3U)的值是4,_Bnd(int,
3U)也是4
4、可变参数函数实现思路
(1)首先在函数里定义一个va_list型的变量,这里是arg_ptr,这个变 量是指向参数的指针。
(2)然后用va_start宏初始化变量arg_ptr,这个宏的第二个参数是第 一个可变参数的前一个参数,是一个固定的参数。
(3)然后用va_arg返回可变的参数,并赋值给整数j. va_arg的第二个参数是你要返回的参数的类型,这里是int型。
(4)最后用va_end宏结束可变参数的获取.然后你就可以在函数里使 用第二个参数了.如果函数有多个可变参数的,依次调用va_arg获 取各个参数。
5、myprintf函数实现
[cpp] view
plain copy
print?
#include <stdio.h>
#include <stdarg.h>
void myprintf(const char *format, ...)
{
va_list ap;
char c;
va_start(ap, format);
while(c = *format++)
{
switch(c)
{
case 'c':
{
char ch = va_arg(ap, int);
putchar(ch);
break;
}
case 's':
{
char *p = va_arg(ap, char *);
fputs(p, stdout);
break;
}
default:
putchar(c);
}
}
va_end(ap);
}
int main(void)
{
myprintf("c\ts\n", '1', "hello");
return 0;
}
相关文章推荐
- C语言中的可变参数
- C语言中可变参数的用法
- C语言关于可变参数函数的例子
- C语言中可变参数函数的设计
- C语言中可变参数的用法——va_list、va_start、va_arg、va_end参数定义
- C语言中如何使用宏 包括单双井号 可变参数
- 详解C语言可变参数 va_list和_vsnprintf及printf实现
- C语言的可变参数
- C语言可变参数
- C语言中可变参数的用法(ZZ)
- c语言宏定义,可变参数的使用
- C语言深入浅出可变参数函数的使用技巧(转)
- c语言可变参数
- C语言中可变参数的用法
- C语言可变参数函数
- C语言可变参数解析
- 【C语言】如何写一个参数可变的函数
- 用C语言实现参数个数可变的函数【转自中国程序员网】
- c语言 之 可变参数列表的应用
- C语言中的可变参数列表