当前位置:首页 » 编程语言 » c语言实现多个可变参数
扩展阅读
webinf下怎么引入js 2023-08-31 21:54:13
堡垒机怎么打开web 2023-08-31 21:54:11

c语言实现多个可变参数

发布时间: 2023-08-30 11:51:19

c语言 怎么写 可变 参数函数

#include<stdarg.h>//可变参数函数必要的头文件
#include<stdio.h>

longintsum(unsignedintargc,...)//可变参数函数必须包含至少一个确定的参数
{
longintsrt=0;
intva;
unsignedinti;
va_listvl;//用于指向可变参数列表
va_start(vl,argc);//初始化,va_start()调用的第一个参数是所编写的可变参数函数的最后一个确定的参数
for(i=0;i<argc;i++){
srt+=(int)va_arg(vl,int);//从参数列表按提取一个int类型的值参与相加运算
}
va_end(vl);//清理
returnsrt;
}
intmain(intargc,char*argv[])
{
printf("%ld ",sum(3,1,2,3));
return0;
}

② C语言中如何获取函数可变参数的个数

这个看你是怎么调用的

一般都是约定个数 或者根据第一个参数,决定个数。

你这个写法,看起来是两个参数调用,然后都是char* 如果是这样

要改成

#include<stdio.h>
#include<stdarg.h>
voidprint(char*value,...)
{
char*t;
printf(value);
va_listval;
va_start(val,value);
t=va_arg(val,char*);//获取下一个参数需要赋值的。
printf(t);
va_end(val);
}

③ 如何在C语言中实现可变长度的参数

C语言实现可变长度字符串,主要依靠realloc函数实现,主要代码如下,
//程序功能,判断插入字符长度len,若大于预设大小n,调整字符串数组大小,实现动态处理数组大小。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char *argv[])
{
char * pstr = NULL;
int n=10;//字符串初始大小
char str[100];//待插入字符串
int len=0;//待插入字符串长度
pstr = (char*)malloc(sizeof(char)*n);//申请sizeof(char)*n个大小的内存空间
if (pstr==NULL)
{
printf("内存申请出错,程序退出!\n");
exit(1);
}

④ c语言如何封装一个带有可变参数的方法

需要借用C语言的VA_LIST宏定义,及相关操作来实现可变参数。

VA_LIST所在头文件:#include <stdarg.h>,用法如下:

(1)首先在函数里定义一具VA_LIST型的变量,这个变量是指向参数的指针;

(2)然后用VA_START宏初始化刚定义的VA_LIST变量;

(3)然后用VA_ARG返回可变的参数,VA_ARG的第二个参数是你要返回的参数的类型(如果函数有多个可变参数的,依次调用VA_ARG获取各个参数);

(4)最后用VA_END宏结束可变参数的获取。

以下是一个自定义打印接口的实现:

intmy_printf(constchar*fmt,...)//...表示参数可变
{
va_listargs;//定义va_list
staticchargc_PrintfOutBuff[1000];
va_start(args,fmt);//初始化
vsnprintf((char*)gc_PrintfOutBuff,1000,(char*)fmt,args);//这里没有使用VA_ARG取回单个变量,而是借用vsnprinf一次性读取。
va_end(args);//结束获取
puts("%s",(constchar*)gc_PrintfOutBuff);//使用。
return0;
}

⑤ C++ 多个函数参数问题

可变参数即表示参数个数可以变化,可多可少,也表示参数的类型也可以变化,可以是int,double还可以是char*,类,结构体等等。可变参数是实现printf(),sprintf()等函数的关键之处,也可以用可变参数来对任意数量的数据进行求和,求平均值带来方便(不然就用数组或每种写个重载)。在C#中有专门的关键字parame,但在C,C++并没有类似的语法,不过幸好提供这方面的处理函数,本文将重点介绍如何使用这些函数。

第一步 可变参数表示
用三个点…来表示,查看printf()函数和scanf()函数的声明:
int printf(const char *, ...);
int scanf(const char *, ...);
这三个点用在宏中就是变参宏(Variadic Macros),默认名称为__VA_ARGS__。如:
#define WriteLine(...) { printf(__VA_ARGS__); putchar('\n');}
再WriteLine("MoreWindows");
考虑下printf()的返回值是表示输出的字节数。将上面宏改成:
#define WriteLine (...) printf(__VA_ARGS__) + (putchar('\n') != EOF ? 1: 0);
这样就可以得到WriteLine宏的返回值了,它将返回输出的字节数,包括最后的’\n’。如下例所示i和j都将输出12。
int i = WriteLine("MoreWindows");
WriteLine("%d", i);
int j = printf("%s\n", "MoreWindows");
WriteLine("%d", j);

第二步 如何处理va_list类型
函数内部对可变参数都用va_list及与它相关的三个宏来处理,这是实现变参参数的关键之处。
在<stdarg.h>中可以找到va_list的定义:
typedef char * va_list;
再介绍与它关系密切的三个宏要介绍下:va_start(),va_end()和va_arg()。
同样在<stdarg.h>中可以找到这三个宏的定义:
#define va_start(ap,v) ( ap = (va_list)&v + _INTSIZEOF(v) )
#define va_end(ap) ( ap = (va_list)0 )
#define va_arg(ap,t) ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )
其中用到的_INTSIZEOF宏定义如下:
#define _INTSIZEOF(n) ( (sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) )
来分析这四个宏:
va_end(ap)这个最简单,就是将指针置成NULL。
va_start(ap,v)中ap = (va_list)&v + _INTSIZEOF(v)先是取v的地址,再加上_INTSIZEOF(v)。_INTSIZEOF(v)就有点小复杂了。( (sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) )全是位操作,看起来有点麻烦,其实不然,非常简单的,就是取整到sizeof(int)。比如sizeof(int)为4,1,2,3,4就取4,5,6,7,8就取8。对x向n取整用C语言的算术表达就是((x+n-1)/n)*n,当n为2的幂时可以将最后二步运算换成位操作——将最低 n - 1个二进制位清 0就可以了。
va_arg(ap,t)就是从ap中取出类型为t的数据,并将指针相应后移。如va_arg(ap, int)就表示取出一个int数据并将指针向移四个字节。
因此在函数中先用va_start()得到变参的起始地址,再用va_arg()一个一个取值,最后再用va_end()收尾就可以解析可变参数了。

第三步 vfprintf()函数和vsprintf()函数
vfprintf()这个函数很重要,光从名字上看就知道它与经常使用的printf()函数有很大的关联。它有多个重载版本,这里讲解最常用的一种:
函数原型
int vfprintf(
FILE *stream,
const char *format,
va_list argptr
);
第一个参数为一个FILE指针。FILE结构在C语言的读写文件必不可少。要对屏幕输出传入stdout。
第二个参数指定输出的格式。
第三个参数是va_list类型,这个少见,但其实就是一个char*表示可变参参数的起始地址。
返回值:成功返回输出的字节数(不包括最后的’\0’),失败返回-1。
vsprintf()与上面函数类似,就只列出函数原型了:
int vsprintf(
char *buffer,
const char *format,
va_list argptr
);
还有一个int _vscprintf(const char *format, va_list argptr );可以用来计算vsprintf()函数中的buffer字符串要多少字节的空间。

代码范例
下面就给出了自己实现的printf()函数(注1)与WriteLine()函数
int Printf(char *pszFormat, ...)
{
va_list pArgList;

va_start(pArgList, pszFormat);
int nByteWrite = vfprintf(stdout, pszFormat, pArgList);
va_end(pArgList);

return nByteWrite;
}

int WriteLine(char *pszFormat, ...)
{
va_list pArgList;

va_start(pArgList, pszFormat);
int nByteWrite = vfprintf(stdout, pszFormat, pArgList);
if (nByteWrite != -1)
putchar('\n'); //注2
va_end(pArgList);

return (nByteWrite == -1 ? -1 : nByteWrite + 1);
}
调用与printf()函数相同。
再给出一个用可变参数来求和,遗憾的在C,C++中无法确定传入的可变参数的个数(printf()中是通过扫描'%'个数来确实参数的个数的),因此要么就要指定个数,要么在参数的最后要设置哨兵数值:
设置哨兵数值:
const int GUARDNUMBER = 0; //哨兵标识
//变参参数的个数无法确定,在printf()中是通过扫描'%'个数,在这通过设置哨兵标识来确定变参参数的终止
int MySum(int i, ...)
{
int sum = i;
va_list argptr;

va_start(argptr, i);
while ((i = va_arg(argptr, int)) != GUARDNUMBER)
sum += i;
va_end(argptr);

return sum;
}
可以这样的调用: printf("%d\n", MySum(1, 3, 5, 7, 9, 0));
但不可以直接传入一个0: printf("%d\n", MySum(0)); //error
指定个数:
int MySum(int nCount, ...)
{
if (nCount <= 0)
return 0;

int sum = 0;
va_list argptr;

va_start(argptr, nCount);
for (int i = 0; i < nCount; i++)
sum += va_arg(argptr, int);
va_end(argptr);

return sum;
}
调用时第一个参数表示后面参数的个数如:
printf("%d\n", MySum(5, 1, 3, 5, 7, 9));
printf("%d\n", MySum(0));
代码所用的头文件:
#include <stdarg.h>
#include <stdio.h>

可变参数的使用方法远远不止上述几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃。

⑥ c语言中什么是参数

如何写可变参数的C函数以及这些可变参数的函数编译器是如何实现的呢?下面是我为大家整理的关于c语言的参数介绍及使用,希望可以帮到大家哦。

简单的可变参数的C函数

下面我们来探讨如何写一个简单的可变参数的C函数.写可变参数的C函数要在程序中用到以下这些宏:

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在这里是variable-argument(可变参数)的意思.

这些宏定义在stdarg.h中,所以用到可变参数的程序应该包含这个头文件.下面我们写一个简单的可变参数的函数,改函数至少有一个整数参数,第二个参数也是整数,是可选的.函数只是打印这两个参数的值.

void simple_va_fun(int i, ...)

{

va_list arg_ptr;

int j=0;

va_start(arg_ptr, i);

j=va_arg(arg_ptr, int);

va_end(arg_ptr);

printf(%d %dn, i, j);

return;

}

我们可以在我们的头文件中这样声明我们的函数:

extern void simple_va_fun(int i, ...);

我们在程序中可以这样调用:

simple_va_fun(100);

simple_va_fun(100,200);

从这个函数的实现可以看到,我们使用可变参数应该有以下步骤:

1)首先在函数里定义一个va_list型的变量,这里是arg_ptr,这个变量是指向参数的指针.

2)然后用va_start宏初始化变量arg_ptr,这个宏的第二个参数是第一个可变参数的前一个参数,是一个固定的参数.

3)然后用va_arg返回可变的参数,并赋值给整数j. va_arg的第二个参数是你要返回的参数的类型,这里是int型.

4)最后用va_end宏结束可变参数的获取.然后你就可以在函数里使用第二个参数了.如果函数有多个可变参数的,依次调用va_arg获取各个参数.

如果我们用下面三种 方法 调用的话,都是合法的,但结果却不一样:

1)simple_va_fun(100);

结果是:100 -123456789(会变的值)

2)simple_va_fun(100,200);

结果是:100 200

3)simple_va_fun(100,200,300);

结果是:100 200

我们看到第一种调用有错误,第二种调用正确,第三种调用尽管结果正确,但和我们函数最初的设计有冲突.下面一节我们探讨出现这些结果的原因和可变参数在编译器中是如何处理的.

可变参数在编译器中的处理

我们知道va_start,va_arg,va_end是在stdarg.h中被定义成宏的,由于1)硬件平台的不同 2)编译器的不同,所以定义的宏也有所不同,下

面以VC++中stdarg.h里x86平台的宏定义摘录如下(''号表示折行):

typedef char * va_list;

#define _INTSIZEOF(n)

((sizeof(n)+sizeof(int)-1)&~(sizeof(int) - 1) )

#define va_start(ap,v) ( ap = (va_list)&v + _INTSIZEOF(v) )

#define va_arg(ap,t)

( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )

⑦ 如何在C语言中定义参数数目可变的函数

定义如下:

<函数返回值> 函数名(形参1, 形参2, ...)

举例说明:

intfunc(inta,intb,...)
{
//函数体
......
}

printf()函数就是一个参数可变的函数,其函数原型为:

intprintf(constchar*__format,...);