首先我们先看看它的头文件是怎么描述的

stdarg.h
#pragma once#ifndef _INC_STDARG
#define _INC_STDARG#if     !defined(_WIN32)
#error ERROR: Only Win32 target supported!
#endif#include <vadefs.h>#define va_start _crt_va_start
#define va_arg _crt_va_arg
#define va_end _crt_va_end#endif  /* _INC_STDARG */
#define _crt_va_arg(ap,t)    (*(t *)((ap += _SLOTSIZEOF(t)+ _APALIGN(t,ap)) \-_SLOTSIZEOF(t)))#include<vadefs.h>
#define _crt_va_arg(ap,t)(*(t *)((ap += _SLOTSIZEOF(t)+_APALIGN(t,ap)) \-_SLOTSIZEOF(t)))
#define _crt_va_end(ap)      ( ap = (va_list)0 )

.va_list用于声明一个变量,我们知道函数的可变参数列表其实就是一个字符串,所以va_list才被声明为字符型指针,这个类型用于声明一个指向参数列表的字符型指针变量
va_start(ap,v),它的第一个参数是指向可变参数字符串的变量,第二个参数是可变参数函数的第一个参数,通常用于指定可变参数列表中参数的个数。
va_arg(ap,t),它的第一个参数指向可变参数字符串的变量,第二个参数是可变参数的类型。
va_end(ap) 用于将存放可变参数字符串的变量清空(赋值为NULL).

接下来看一个例子

static struct ExprNode * MakeExprNode(enum Token_Type opcode, ...) {struct ExprNode *ExprPtr = new (struct ExprNode);
va_list ArgPtr;ExprPtr->OpCode = opcode; // 接受记号的类别va_start(ArgPtr, opcode);switch(opcode) {    // 根据记号的类别构造不同的节点case CONST_ID: // 常数ExprPtr->Content.CaseConst = (double)va_arg(ArgPtr, double);break;case T:ExprPtr->Content.CaseParmPtr = &Parameter;break;case FUNC:ExprPtr->Content.CaseFunc.MathFuncPtr = (FuncPtr)va_arg(ArgPtr, FuncPtr);ExprPtr->Content.CaseFunc.Child = (struct ExprNode *) va_arg(ArgPtr, struct ExprNode *);break;default:ExprPtr->Content.CaseOperator.Left = (struct ExprNode *)va_arg(ArgPtr, struct ExprNode *);ExprPtr->Content.CaseOperator.Right = (struct ExprNode *)va_arg(ArgPtr, struct ExprNode *);break;}va_end(ArgPtr);return ExprPtr;
}

上述代码是语法分析的生成语法树的一个实现代码;通过这段代码我们能看清楚的是
va_start的功能是要把ap指针指向可变参数的第一个参数位置去
#define _crt_va_start(ap,v) ( ap = (va_list)_ADDRESSOF(v) + _INTSIZEOF(v) )
. va_arg是要从ap中取下一个参数,即第一个参数。以此类推。
#define _crt_va_arg(ap,t) ( (t )((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )
注意加粗的ap 实际上是等于 ap = ap + ……;
. va_end(ap) 将声明的ap指针置为空,因为指针使用后最后设置为空

Va_list Va_start va_arg Va_end 的用法相关推荐

  1. va_list/va_start/va_arg/va_end深入分析

    va_list/va_start/va_arg/va_end这几个宏,都是用于函数的可变参数的. 我们来看看在vs2008中,它们是怎么定义的: 1: ///stdarg.h 2: #define v ...

  2. 变长参数va_list va_start va_arg va_end

    对于int printf(const char *format, ...);这种变长参数,需要使用va_list va_start va_end va_arg来访问参数. 下面是一个tutorials ...

  3. C语言使用函数参数传递中的省略号:va_list, va_start, va_arg, va_end

    首先要处理这种省略号的参数的话,需要包含头文件#include <stdarg.h>,然后利用下面的函数对"..."省略号变量进行处理. va_list arg; ty ...

  4. 如何获取函数的变长参数(va_list, va_start, va_arg, va_end)

    最近在花时间研读C++. 函数这章讲到了函数的变长参数(ellipsis...),但是primer中讲得比较浅,提到了怎么声明怎么调用,但是没有写明在函数内部是如何获取变长的参数的. 1)省略号(el ...

  5. 可变参数:va_list(),va_start(),va_arg(),va_end() 详细解析

    目录 1.含义: 2.使用: 3.连续打印出自定义格式的文字: 1.含义: (1)va_list是C语言中的一个宏定义,用于表示一个变长参数列表.它是一个指向变长参数列表的指针,可以通过宏va_sta ...

  6. va_list、va_start和va_end的用法

    在项目的代码中看到函数不定参数的使用,现在总结一下va_list.va_start和va_end三个宏的用法. c语言提供了函数的不定长参数使用,比如 void func(int a, -).三个省略 ...

  7. 可变参数的函数,va_start(), va_arg(), va_end()

    头文件 stdarg:类型va_list:宏va_start:宏va_arg:宏va_end 1 #include <stdio.h>2 #include <stdarg.h> ...

  8. va_list/va_start/va_end的使用

    va_list 键入以保存有关变量参数的信息 va_start 初始化变量参数列表 初始化ap以检索参数paramN后面的附加参数. 调用va_start的函数在返回之前也应调用va_end. 参数不 ...

  9. c语言va_start函数,va_start和va_end,以及c语言中的可变参数原理

    FROM:http://www.cnblogs.com/hanyonglu/archive/2011/05/07/2039916.html 本文主要介绍va_start和va_end的使用及原理. 在 ...

最新文章

  1. 全球20大智慧城市排行榜揭晓:无锡列中国第一,银川、杭州上榜!
  2. Quartz-SimpleTrigger解读
  3. UIPopoverController的使用
  4. rwkj 1359 友元:两点距离
  5. HDU1054 Strategic Game
  6. How to think positively 如何培养正念
  7. 信用卡消费退款,商家让客户付手续费,合理吗?
  8. 内网渗透中SSh的巧用
  9. 虚拟机登录/系统管理等命令
  10. 【转】郭敬明作品中100句经典的话
  11. 爱普生R230打印机清零
  12. 和巨耀通杯计算机基础知识大赛,南京邮电大学第二十二届科技节活动之 “和巨耀通杯”网页设计大赛圆满落幕...
  13. 黑马java学习笔记4 强化部分 常见API
  14. [NOIP2018 普及组] 龙虎斗
  15. kettle 教程(四):自定义 Java 代码
  16. Dagger2基本使用与原理
  17. 魄罗盒子一直显示连接服务器失败,英雄联盟安装错误代码7001004怎么办 | 手游网游页游攻略大全...
  18. 宝藏又小众的西方立绘文字游戏素材网站分享
  19. 压阻式压力传感器的分类与原理
  20. AutoIt自动化实例

热门文章

  1. java 数独算法_java版数独游戏核心算法(一)
  2. MT7921:通过BLE发送指定UUID的广播
  3. 日常实用英语表达个人总结(1)
  4. 笔加学堂 | 破解35岁职业黑洞,你可以尝试着这么做!
  5. 关于工信部批准发布138项通信行业标准等876项行业标准的公告
  6. QoS服务质量五QoS边界行为之流量整形
  7. Unity标准开发实例——Shuriken粒子系统06
  8. 市场上最常见的国际期货软件是什么?
  9. 建个网站要多少钱 决定网站建设价格的四个因素
  10. 计算机毕业设计(附源码)python作业批改管理系统