c 语言函数可变参数的处理

/*************************************************************************
    > File Name: va_list.c
    > Author: zshh0604
    > Mail: [email protected]
    > Created Time: 2014年10月14日 星期二 15时16分09秒
 ************************************************************************/
#include<stdio.h>
/***
	在 c中使用可变参数,

	c语言中提供一个va_list类型要存储函数的可变参数。

1.在c语言中定义函数的可变参数方法如下:

	一:该参数必须在最后。
	二:最后一个参数必须声明可变参数的类型。如下
	三:可以参数是使用三点表示。
	四:在函数调用的使用通过fmt这个字符参数进行参数类型和参数个数的设定。如:"%s%d%c%f"

	void test(char *fmt,...);

2.如果使用可变参数。
	c提供一个如下一组函数:
		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);
	对可变参数进行操作。函数原型。

		void va_start(va_list ap,last);

		函数功能:
			将ap依次指向可变参数。
		函数参数:
			ap:会依次指向每一个可变参数。
			last:是fmt,它的作用是,规定了参数可变参数的个数,和类型。
		函数返回值:
			没有返回值。

		在调用该组函数之前必须先调用va_start()函数。

		通过fmt格式化字符中的格式。来一次获取该参数的值。

		char *s;
		int d;
		char c;
		while(*fmt)
		{
			switch(*fmt++)
			{
				 	case 's':
						s = va_arg(ap, char *);
						break;
					case 'd':
						d = va_arg(ap, int);
						break;
					case 'c':
						c = va_arg(ap, char);
						break;
			}
		}
		va_end(ap);
		在函数结束前,必须调用va_end()函数。

		使用vsnprintf()直接使用ap.	

		vsnprintf():函数原型如下:
        int vsnprintf(char *str, size_t size, const char *format, va_list ap);

		该方法使用如下:

	//  va_list	的作用:
	//  头文件<stdarg.h>提供了遍历未知数据和类型的函数参数表的功能。
	//  那么,在函数f内声明一个类型为va_list的变量ap.它将依次指向每个实际的参数。
	//
	//		va_list ap;
	//
	//		在访问任何未命名的参数前,必须使用va_start宏初始化ap一次。
	//
	//		va_start(va_list ap,lastarg);
	//
	//		此后每次执行宏va_arg都将产生一个与下一个未命令的参数具有相同类型和数值的值。
	//		它同时还修改ap,以使得下一次执行va_arg时返回下一个参数。
	//
	//		 类型 va_arg(va_list ap,类型);
	//
	//		 void ve_end(va_list ap);
	//
	//       在所有处理的参数处理完毕之后。且在退出f之前,必须调用宏va_end一次。
	//
	//       void va_end(va_list ap);

**/

/*************************************************************************
  > File Name: snprintf.c
  > Author: zshh0604
  > Mail: [email protected]
  > Created Time: 2014年10月14日 星期二 13时21分13秒
 ************************************************************************/
#include<stdlib.h>
#include<stdio.h>
#include<stdarg.h>
char * make_message(const char *fmt, ...)
{

	int n;				/* 用来记录vsnprintf()的返回之。 如果这个值小于等于-1,寿命。分配的空间不够。
						   如果这个值大于-1,但是n不小于size,那么应该把该值加1,(size+1),否则将空间加大一倍 ***/

	int size = 100;     /* Guess we need no more than 100 bytes. */
	char *p, *np;
	va_list ap;

	if ((p = malloc(size)) == NULL)
		return NULL;
	while (1) {
		/* Try to print in the allocated space. */

		va_start(ap, fmt);       //通过这个函数,使得ap指向可变参数中每一个参数。
		n = vsnprintf(p, size, fmt, ap);  //将ap指向的参数格式化到p中。p的最大大小为size.按照fmt格式打印。
		va_end(ap);						  //使用结束之后,调用va_end(ap);函数。

		/* If that worked, return the string. */

		if (n > -1 && n < size)
			return p;

		/* Else try again with more space. */

		if (n > -1)    /* glibc 2.1 */
			size = n+1; /* precisely what is needed */
		else           /* glibc 2.0 */
			size *= 2;  /* twice the old size */

		if ((np = realloc (p, size)) == NULL) {

			free(p);
			return NULL;
		} else {
			p = np;
		}
	}
}

时间: 2024-12-18 09:46:30

c 语言函数可变参数的处理的相关文章

C语言函数可变参数列表

C语言允许使用可变参数列表,我们常用的printf函数即为可变参数函数,C标准库提供了stdarg.h为我们提供了这方面支持:该头文件提供了一些类型和宏来支持可变参数列表,包括类型va_list,宏va_start.va_arg.va_end: 可变函数参数定义方法: #include <stdarg.h> void func(int count,...){ va_list ap; int ix, tmp; va_start(ap, a); for(ix=0;ix < count; ++

C语言之函数可变参数

先上一段代码: #include<cstdarg> #include<iostream> #include<string> using namespace std; void error(char* format,...){//至少要有一个参数,后边的...表示参数可变 va_list ap; int d,flag; char c, *s; va_start(ap,*format);//从args参数开始后面都是可变参数,va_start,va_end都为宏 while

C语言中可变参数的函数(三个点,“...”)

C语言中可变参数的函数(三个点,"...") 本文主要介绍va_start和va_end的使用及原理. 在以前的一篇帖子Format MessageBox 详解中曾使用到va_start和va_end这两个宏,但对它们也只是泛泛的了解. 介绍这两个宏之前先看一下C中传递函数的参数时的用法和原理: 1.在C中,当我们无法列出传递函数的所有实参的类型和数目时,可以用省略号指定参数表 void foo(...); void foo(parm_list,...); 这种方式和我们以前认识的不大

PHP函数可变参数列表的具体实现方法介绍

PHP函数可变参数列表可以通过_get_args().func_num_args().func_get_arg()这三个函数来实现.我们下面就对此做了详细的介绍. AD:2014WOT全球软件技术峰会北京站 课程视频发布 也许对于PHP初级程序员来说,对于PHP函数并不能完全熟练的掌握.我们今天为大家介绍的PHP函数可变参数列表的实现方法主要是利用func_get_args().func_num_args().func_get_arg()这三个系统函数来实现的,其中func_get_args()

c#编程基础之函数可变参数

可变参数:int sum (params int[] values)int sum (string name,params int[] values) 注意:params参数必须是形参表中的最后一个参数. 代码如下: using System; using System.Collections.Generic; using System.Text; namespace 函数可变参数学习 { class Program { static void Main(string[] args) { Say

Python新手学习基础之函数-可变参数*

可变参数( * ) 可变参数,顾名思义,它的参数是可变的,比如列表.字典等.如果我们需要函数处理可变数量参数的时候,就可以使用可变参数. 我们在查看很多Python源码时,经常会看到 某函数(*参数1, **参数2)这样的函数定义,这个*参数和**参数就是可变参数,一时会让人有点费解.其实只要把函数可变参数的定义搞清楚了,就不难理解了. 当我们不知道需要用几个参数来定义函数的时候,可变参数就可以大展手脚了. 在Python里,带 * 的参数就是用来接受可变数量参数的. 如果一个函数定义如下: d

php课外笔记--函数可变参数列表的实现

php课外笔记--函数可变参数列表的实现 php的函数方面非常强大,但对于一些php新手来说,理解有部分困难,不能完全熟练的掌握. php培训教程中,介绍一部分函数可变参数列表的实现方法: PHP函数可变参数列表的实现方法主要是利用func_get_args().func_num_args().func_get_arg()这三个系统函数来实现的,其中func_get_args()函数以数组的形式获得参数列表,具体用法参看手册. PHP函数可变参数列表代码如下: < ?php    /*   函数

深度探索C语言函数可变长参数

通常我们使用的C函数的参数个数都是固定的,但也有不固定的.比如printf()与scanf().如何自己动手实现一个可变参数函数,这个还是有点技巧的. 我们最常用的就是定义一个宏,使用printf或者printk,如下 #define wwlogk(fmt, args...) printk(fmt, ## args) 现在我们自己动手实现一个可变参数的函数,后面分析原理.首先看一个例子: #include <stdio.h> #include <stdarg.h> int Sum(

C语言中可变参数函数实现原理

C函数调用的栈结构 可变参数函数的实现与函数调用的栈结构密切相关,正常情况下C的函数参数入栈规则为__stdcall, 它是从右到左的,即函数中的最右边的参数最先入栈.例如,对于函数: void fun(int a, int b, int c) { int d; ... } 其栈结构为 0x1ffc-->d 0x2000-->a 0x2004-->b 0x2008-->c 对于在32位系统的多数编译器,每个栈单元的大小都是sizeof(int), 而函数的每个参数都至少要占一个栈单