C语言可变参数va_list
一、什么是可变参数
在C语言编程中有时会遇到一些参数个数可变的函数,例如printf(),scanf()函数,其函数原型为:
int printf(const char* format,…)
int scanf(const char *format,…)
它除了有一个参数format固定以外,后面跟着的参数的个数和类型是可变的(用三个点“…”做参数占位符)
二、简单的可变参数例子
#include <stdio.h>
#include <stdarg.h>
void print_args(int count, ...);
int main(int argc, char* argv[]) {
print_args(5,1,2,3,4,5);
return 0;
}
void print_args(int count, ...) {
int i, value;
va_list arg_ptr;
va_start(arg_ptr, count);
for(i=0; i<count; i++) {
value = va_arg(arg_ptr,int);
printf("position %d = %d\n", i+1, value);
}
va_end(arg_ptr);
}
三、对va_arg,va_list,va_start,va_end剖析
可变参数用到以下宏函数:
原型: void va_start(va_list arg_ptr, prev_param); 功能:以固定参数的地址为起点确定变参的内存起始地址,获取第一个参数的首地址
返回值:无
原型:va_list 类型的变量,va_list arg_ptr ,这个变量是指向参数地址的指针,因为得到参数的地址之后,再结合参数的类型,才能得到参数的值。
原型:type va_arg(va_list arg_ptr, type); 功能:获取下一个参数的地址 返回值:根据传入参数类型决定返回值类型
原型:void va_end(va_list arg_ptr); 功能:将 arg_ptr 指针置0 返回值:无
对应于上面的实例,参见下面的示意图,即可明白,
| 5 | | 5 | /\ | 5 | <--arg_ptr
| 4 | | 4 | || | 4 |
| 3 | | 3 | || | 3 |
| 2 | | 2 | || | 2 |
| 1 | | 1 | <-- arg_ptr || | 1 |
| 5 | <-- count | 5 | <-- count || | 5 | <-- count
这三个宏的实现细节,可参见下面的 blog:
[1] C中可变参数函数实现
C语言可变参数va_list的更多相关文章
- C语言 可变参数
一.基础部分 1.1 什么是可变长参数 可变长参数:顾名思义,就是函数的参数长度(数量)是可变的.比如 C 语言的 printf 系列的(格式化输入输出等)函数,都是参数可变的.下面是 printf ...
- 转:C语言 可变参数
C语言 可变参数 堆栈一般是怎么压栈处理的 /* * stack space: * * 参数3 | up * 参数2 | * 参数1 v ...
- 深入C语言可变参数(va_arg,va_list,va_start,va_end,_INTSIZEOF)
一.什么是可变参数 在C语言编程中有时会遇到一些参数个数可变的函数,例如printf(),scanf()函数,其函数原型为: int printf(const char* format,…),int ...
- C语言可变参数函数实现原理
一.可变参数函数实现原理 C函数调用的栈结构: 可变参数函数的实现与函数调用的栈结构密切相关,正常情况下C的函数参数入栈规则为__stdcall, 它是从右到左的,即函数中的最右边的参数最先入栈. 本 ...
- ios 可变参数(va_list,va_start,va_end)
例如:UIAlertView的init方法中的otherButtonTitles:(NSString *)otherButtonTitles, ...等多个可变参数. ios实现传递不定长的多个参数的 ...
- C语言可变参数函数的编写
1. 引言 C语言我们接触的第一个库函数是 printf(“hello,world!”);其参数个数为1个. 然后,我们会接触到诸如: printf(“a=%d,b=%s,c=%c”,a,b,c);此 ...
- C语言可变参数
前段时候在实现利用redis进行的一个数据库比对的功能,稍微去分析了一下redis里面的源代码,然后发现其中的发送命令接口声明如下: void *redisCommand(redisConnect * ...
- c语言可变参数函数
c语言支持可变参数函数.这里的可变指,函数的参数个数可变. 其原理是,一般情况下,函数参数传递时,其压栈顺序是从右向左,栈在虚拟内存中的增长方向是从上往下.所以,对于一个函数调用 func(int a ...
- Go语言 可变参数
最近与同事讨论时,提到Go语言的可变参数,之前没有总结过相关知识点,今天我们介绍一下Go语言的可变参数. 可变参数(Variable Parameters):参数数量可变的函数称之为可变参数函数,主要 ...
随机推荐
- AngularJS进阶(二十二)实现时间选择插件
JS实现时间选择插件 引导语 在项目开发过程中,需要实现根据以日期为筛选条件之一,故需要实现时间选择插件.对于未接触的新事物,自己总是感觉不明觉厉.其实,有些实现可以使用很简单的方法即可.以此为例,偶 ...
- OAF隐藏显示题头
当一个页面的内容较多时,我们需要将内容进行分组显示.这个时候我们就需要用到隐藏显示. 本文将介绍如何使用OAF的隐藏显示题头功能 一.新建AM 在test.oracle.apps.cux上点右键,选择 ...
- android 高仿京东
android 高仿京东源码,两年前的作品,最近发现一些老代码,发布出来给初学者学习,下面附上几张展示的效果,有需要的请到下面地址下载,记得stare哦 https://github.com/xian ...
- RGB颜色转换算法C语言实现
typedef unsigned short TUINT16; #define RGB565(R, G, B) \ (((TUINT16) ((R) >> 3)) << ...
- sxoi爆炸祭
好吧,纯粹是去玩玩的,我这么一个弱省的蒟蒻,进队纯粹是开玩笑.... Day0 去五中试机,感觉电脑手感不错,打了半个线段树的板子才发现试机要在自己的电脑上试,然后我无奈的搬东西(从26号搬到2号), ...
- ubuntu18.04 安装mysql 5.7.22
后台下载,脱离终端控制 后台下载,可以节省ssh资源占用,且不会因为ssh连接断开而导致下载失败,适用于操作远端云服务器 wget -b 启动后台下载 -o 指定logfile(记录下载进度信息) w ...
- Dapper.SimpleCRUD mysql 插入数据时出现的小插曲
最近想玩一下.net dapper,然后在nuget包中搜索看到了 Dapper.SimpleCRUD ,然后我等好奇心重的小骚年,内心又开始跃跃欲试. 使用sqlserver数据库时没有遇到问题,既 ...
- RocketMQ源码 — 六、 RocketMQ高可用(1)
高可用究竟指的是什么?请参考:关于高可用的系统 RocketMQ做了以下的事情来保证系统的高可用 多master部署,防止单点故障 消息冗余(主从结构),防止消息丢失 故障恢复(本篇暂不讨论) 那么问 ...
- 01_Linux学习_基础知识
学Linux就学命令行 === cd / 转到根目录,相对当前路径 cd dev 转到dev目录 whoami 查阅当前用户 pwd 查阅当前目录 ls 查阅当前目录下的目录和文件 === Linux ...
- .net c#获取自定义Attribute
前言: 在c#开发中,有时候我们需要读取 Attribute中的信息(关于Attribute , 我自己把他理解成一个可以为类,属性标记的东西,这个标记可以为你提供一些关于类,方法,属性的额外信息) ...