龙华网站建设公司,特色美食网站建设,网站开发技术实验报告,wordpress导航菜单居中本篇博客让我们来认识一下C语言学习过程中往往被忽略的可变参数列表 所谓可变参数#xff0c;就是一个不限定参数数量的函数#xff0c;我们可以往里面传入任意个数的参数#xff0c;以达成某些目的。 
关联#xff1a;C11可变模板参数#xff1b;本文首发于 慕雪的寒舍 
…本篇博客让我们来认识一下C语言学习过程中往往被忽略的可变参数列表 所谓可变参数就是一个不限定参数数量的函数我们可以往里面传入任意个数的参数以达成某些目的。 
关联C11可变模板参数本文首发于 慕雪的寒舍 
1.函数 
#include stdarg.hvoid 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);1.1 va_start 
void va_start(va_list ap, last_arg);ap: 这是一个 va_list 类型的对象它用来存储通过 va_arg 获取额外参数时所必需的信息这个函数的作用是初始化 ap 变量它与 va_arg 和 va_end 函数一起使用。 
last_arg 是最后一个传递给函数的已知的固定参数即省略号之前的参数。 
要想设置一个带可变参数的函数函数声明是下面这样的 
void test(int a,int b, ...);这里出现的省略号就是可变参数的特征而变量b就是va_start函数需要的last_arg 
1.2 va_arg 
type va_arg(va_list ap, type);这个函数的作用是来提取可变参数列表中的参数。注意每次提取的参数是直接返回的并没有放到变量ap中。 
每次对va_arg的调用都会修改ap以便下次调用时返回下一个参数推断参数的时候需要指定type如果当前参数类型和type不统一就会发生不可预知的错误man手册里面说的 
If ap is passed to a function that uses va_arg(ap,type) then the value of ap is undefined after the return of that function.如果ap被传递给va_arg(ap,type)则在该函数返回后ap的值未定义。 
1.3 va_end 
void va_end(va_list ap);每一个va_start都需要有一个配套的va_end其用于清空ap 
可以把他俩的关系理解为malloc/free记得加上就行 
1.4 va_copy 
这个函数的作用是将可变参数列表从第二个参数src拷贝到第一个参数dest 
void va_copyva_list destva_list src;其也能够初始化dest。调用了va_copy后无须调用va_start初始化dest但va_end还是需要的。 
2.简单示例 
2.1 打印多个参数 
#includestdarg.h
#includestdio.h
int print(int num_args,...)
{va_list ap;va_start(ap,num_args);//初始化可变参数for(int i0;inum_args;i){printf(%d ,va_arg(ap,int));}printf(\n);va_end(ap);//结束对ap的使用
}int main()
{print(5,1,2,3,4,5,6,7,8,9);return 0;
}运行该函数会打印如下结果 
$ ./test
1 2 3 4 5 这就表明了...省略号之前的参数和va_arg返回可变参数其实是没有关系的。 
int print(int num_args,...)
{va_list ap;va_start(ap,num_args);//初始化可变参数for(int i0;i8;i){printf(%d ,va_arg(ap,int));}printf(\n);va_end(ap);//结束对ap的使用
}int main()
{print(5,1,2,3,4,5,6,7,8,9,10);return 0;
}即便在最后都没有使用num_args也不会影响结果的正确性。va_start需要这个参数其实是用来标识可变参数的起点。 
$ ./test
1 2 3 4 5 6 7 8 2.2 多参数求和 
#includestdarg.h
#includestdio.h
// 采用可变参数第一个参数用于标识参数数量
int sum(int num_args, ...)
{int val  0;va_list ap;int i;va_start(ap, num_args);for(i  0; i  num_args; i){val  va_arg(ap, int);}va_end(ap);return val;
}void test1()
{printf(10、20 和 30 的和  %d\n,  sum(3, 10, 20, 30) );printf(4、20、25 和 30 的和  %d\n,  sum(4, 4, 20, 25, 30) );
}运行如下 
$ ./test
10、20 和 30 的和  60
4、20、25 和 30 的和  793.利用可变参数实现log类 
现在有了可变参数我们就可以接用这个参数来进行日志的打印了 
#pragma once#include cstdio
#include ctime
#include cstdarg
#include cassert
#include cstring
#include cerrno
#include stdlib.h#define DEBUG 0
#define NOTICE 1
#define WARINING 2
#define FATAL 3const char *log_level[]{DEBUG, NOTICE, WARINING, FATAL};// 采用可变参数列表
void logging(int level, const char *format, ...)
{assert(level  DEBUG || level  FATAL);char *name  getenv(USER);// 获取环境变量中的用户执行命令的用户char logInfo[1024];// 获取可变参数列表va_list ap; // ap - char*va_start(ap, format);vsnprintf(logInfo, sizeof(logInfo)-1, format, ap);va_end(ap); // ap  NULL// 根据日志等级选择打印到stderr/stdoutFILE *out  (level  FATAL) ? stderr:stdout;// 格式化打印到文件中fprintf(out, %s | %u | %s | %s\n, \log_level[level], \(unsigned int)time(nullptr),\name  nullptr ? unknow:name,\logInfo);
}3.1 vsnprint 
作用使用vsnprintf()用于向一个字符串缓冲区打印格式化字符串且可以限定打印的格式化字符串的最大长度。 
此函数需要C99或者C11及以上版本才能支持。 
int vsnprintf(char* sbuf, size_t n, const char* format, va_list arg);第一个参数目标缓冲区字符数组第二个参数限定最多打印到缓冲区的字符数量为n-1个留位置给\0第三个参数打印的格式如%d:%s第四个参数可变参数arg需要用va_start初始化 
返回成功打印到sbuf中的字符的个数不包括末尾追加的\0。如果格式化解析失败则返回负数。 
用这个函数就能把我们的来源字符串给输入到缓冲区char logInfo[1024];中 
3.2 fprintf 
使用fprintf将printf的输出打印到指定文件中用法和printf是一样的 
int fprintf(FILE *stream, const char *format, ...);这样是为了区分stderr/stdout。同时添加上执行命令的用户信息以及当前的时间戳 fprintf(out, %s | %u | %s | %s\n, \log_level[level], \(unsigned int)time(nullptr),\name  nullptr ? unknow:name,\logInfo);3.3 运行结果 
int main()
{logging(DEBUG, socket create success: %d, 114514);logging(FATAL, socket:%s:%d, strerror(errno), 11234);return 0;
}$ ./test
DEBUG | 1675322313 | muxue | socket create success: 114514
FATAL | 1675322313 | muxue | socket:Success:11234The end 
对于可变参数的简单介绍就到这里基本的使用能看懂久OK啦 文章转载自: http://www.morning.clyhq.cn.gov.cn.clyhq.cn http://www.morning.cywf.cn.gov.cn.cywf.cn http://www.morning.sgnjg.cn.gov.cn.sgnjg.cn http://www.morning.lgznf.cn.gov.cn.lgznf.cn http://www.morning.bnxfj.cn.gov.cn.bnxfj.cn http://www.morning.stflb.cn.gov.cn.stflb.cn http://www.morning.jrlgz.cn.gov.cn.jrlgz.cn http://www.morning.bhwll.cn.gov.cn.bhwll.cn http://www.morning.qpqwb.cn.gov.cn.qpqwb.cn http://www.morning.jcwt.cn.gov.cn.jcwt.cn http://www.morning.mttck.cn.gov.cn.mttck.cn http://www.morning.gblrn.cn.gov.cn.gblrn.cn http://www.morning.hnrqn.cn.gov.cn.hnrqn.cn http://www.morning.bqwsz.cn.gov.cn.bqwsz.cn http://www.morning.bpcf.cn.gov.cn.bpcf.cn http://www.morning.wwsgl.com.gov.cn.wwsgl.com http://www.morning.qwwcf.cn.gov.cn.qwwcf.cn http://www.morning.cltrx.cn.gov.cn.cltrx.cn http://www.morning.bmyrl.cn.gov.cn.bmyrl.cn http://www.morning.tsflw.cn.gov.cn.tsflw.cn http://www.morning.kfysh.com.gov.cn.kfysh.com http://www.morning.prhfc.cn.gov.cn.prhfc.cn http://www.morning.lktjj.cn.gov.cn.lktjj.cn http://www.morning.dhqyh.cn.gov.cn.dhqyh.cn http://www.morning.qyfrd.cn.gov.cn.qyfrd.cn http://www.morning.jpkhn.cn.gov.cn.jpkhn.cn http://www.morning.nnqrb.cn.gov.cn.nnqrb.cn http://www.morning.tkchg.cn.gov.cn.tkchg.cn http://www.morning.fbmjw.cn.gov.cn.fbmjw.cn http://www.morning.wfmqc.cn.gov.cn.wfmqc.cn http://www.morning.zkgpg.cn.gov.cn.zkgpg.cn http://www.morning.symgk.cn.gov.cn.symgk.cn http://www.morning.trbxt.cn.gov.cn.trbxt.cn http://www.morning.lwzgn.cn.gov.cn.lwzgn.cn http://www.morning.pngfx.cn.gov.cn.pngfx.cn http://www.morning.xqkcs.cn.gov.cn.xqkcs.cn http://www.morning.ktfbl.cn.gov.cn.ktfbl.cn http://www.morning.tralution.cn.gov.cn.tralution.cn http://www.morning.clbgy.cn.gov.cn.clbgy.cn http://www.morning.rgrz.cn.gov.cn.rgrz.cn http://www.morning.hmmtx.cn.gov.cn.hmmtx.cn http://www.morning.rwyw.cn.gov.cn.rwyw.cn http://www.morning.xfmwk.cn.gov.cn.xfmwk.cn http://www.morning.hyhzt.cn.gov.cn.hyhzt.cn http://www.morning.cwjxg.cn.gov.cn.cwjxg.cn http://www.morning.qxmnf.cn.gov.cn.qxmnf.cn http://www.morning.lwgrf.cn.gov.cn.lwgrf.cn http://www.morning.ysbrz.cn.gov.cn.ysbrz.cn http://www.morning.spsqr.cn.gov.cn.spsqr.cn http://www.morning.dwgcx.cn.gov.cn.dwgcx.cn http://www.morning.nrfrd.cn.gov.cn.nrfrd.cn http://www.morning.lhhdy.cn.gov.cn.lhhdy.cn http://www.morning.kyhnl.cn.gov.cn.kyhnl.cn http://www.morning.btwlp.cn.gov.cn.btwlp.cn http://www.morning.fmqng.cn.gov.cn.fmqng.cn http://www.morning.jfzbk.cn.gov.cn.jfzbk.cn http://www.morning.mxhcf.cn.gov.cn.mxhcf.cn http://www.morning.yqgbw.cn.gov.cn.yqgbw.cn http://www.morning.ygbq.cn.gov.cn.ygbq.cn http://www.morning.nmbbt.cn.gov.cn.nmbbt.cn http://www.morning.qsy36.cn.gov.cn.qsy36.cn http://www.morning.zlxrg.cn.gov.cn.zlxrg.cn http://www.morning.gnghp.cn.gov.cn.gnghp.cn http://www.morning.yzxhk.cn.gov.cn.yzxhk.cn http://www.morning.ie-comm.com.gov.cn.ie-comm.com http://www.morning.jmwrj.cn.gov.cn.jmwrj.cn http://www.morning.qklff.cn.gov.cn.qklff.cn http://www.morning.dmtbs.cn.gov.cn.dmtbs.cn http://www.morning.i-bins.com.gov.cn.i-bins.com http://www.morning.mtrrf.cn.gov.cn.mtrrf.cn http://www.morning.psxwc.cn.gov.cn.psxwc.cn http://www.morning.mngh.cn.gov.cn.mngh.cn http://www.morning.rdlrm.cn.gov.cn.rdlrm.cn http://www.morning.rxnl.cn.gov.cn.rxnl.cn http://www.morning.lpgw.cn.gov.cn.lpgw.cn http://www.morning.bxsgl.cn.gov.cn.bxsgl.cn http://www.morning.bmrqz.cn.gov.cn.bmrqz.cn http://www.morning.pzlhq.cn.gov.cn.pzlhq.cn http://www.morning.rpzqk.cn.gov.cn.rpzqk.cn http://www.morning.wplbs.cn.gov.cn.wplbs.cn