一、什么是可变参数

在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中可变参数函数实现

[2] 内存对齐 _INTSIZEOF(n)

C语言可变参数va_list的更多相关文章

  1. C语言 可变参数

    一.基础部分 1.1 什么是可变长参数 可变长参数:顾名思义,就是函数的参数长度(数量)是可变的.比如 C 语言的 printf 系列的(格式化输入输出等)函数,都是参数可变的.下面是 printf ...

  2. 转:C语言 可变参数

    C语言 可变参数 堆栈一般是怎么压栈处理的 /* * stack space: * *        参数3   |    up *        参数2   | *        参数1   v   ...

  3. 深入C语言可变参数(va_arg,va_list,va_start,va_end,_INTSIZEOF)

    一.什么是可变参数 在C语言编程中有时会遇到一些参数个数可变的函数,例如printf(),scanf()函数,其函数原型为: int printf(const char* format,…),int ...

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

    一.可变参数函数实现原理 C函数调用的栈结构: 可变参数函数的实现与函数调用的栈结构密切相关,正常情况下C的函数参数入栈规则为__stdcall, 它是从右到左的,即函数中的最右边的参数最先入栈. 本 ...

  5. ios 可变参数(va_list,va_start,va_end)

    例如:UIAlertView的init方法中的otherButtonTitles:(NSString *)otherButtonTitles, ...等多个可变参数. ios实现传递不定长的多个参数的 ...

  6. C语言可变参数函数的编写

    1. 引言 C语言我们接触的第一个库函数是 printf(“hello,world!”);其参数个数为1个. 然后,我们会接触到诸如: printf(“a=%d,b=%s,c=%c”,a,b,c);此 ...

  7. C语言可变参数

    前段时候在实现利用redis进行的一个数据库比对的功能,稍微去分析了一下redis里面的源代码,然后发现其中的发送命令接口声明如下: void *redisCommand(redisConnect * ...

  8. c语言可变参数函数

    c语言支持可变参数函数.这里的可变指,函数的参数个数可变. 其原理是,一般情况下,函数参数传递时,其压栈顺序是从右向左,栈在虚拟内存中的增长方向是从上往下.所以,对于一个函数调用 func(int a ...

  9. Go语言 可变参数

    最近与同事讨论时,提到Go语言的可变参数,之前没有总结过相关知识点,今天我们介绍一下Go语言的可变参数. 可变参数(Variable Parameters):参数数量可变的函数称之为可变参数函数,主要 ...

随机推荐

  1. AngularJS进阶(二十三)ANGULAR三宗罪之版本陷阱

    ANGULAR三宗罪之版本陷阱 坑!碰到个大坑,前面由于绑定日期时将angular版本换为angular-1.3.0-beta.1时,后来午睡后,登录系统,发现无论如何都登陆不进去了,经过调试,发现数 ...

  2. 算法精解:最小二乘法C实现

    计量经济学研究的直接目的是确定总体回归函数Yi=B1+B2Xi+ui,然而能够得到的只是来自总体的若干样本的观测值,要用样本信息建立的样本回归函数尽可能"接近"地去估计总体回归函数 ...

  3. C/C++中关键字static的用法及作用

    本文将主要从static在C和C++共有的作用及C++特有的作用两个方面进行解析. 在C和C++中共有的作用 隐藏(对变量.函数均可) 当同时编译多个文件时,所有未加static前缀的全局变量或全局函 ...

  4. LeetCode之“动态规划”:Minimum Path Sum && Unique Paths && Unique Paths II

    之所以将这三道题放在一起,是因为这三道题非常类似. 1. Minimum Path Sum 题目链接 题目要求: Given a m x n grid filled with non-negative ...

  5. windows c/c++ 代码运行时间,毫秒级

    #pragma once /* //计算代码段运行时间的类 // */ #include <iostream> #ifndef ComputeTime_h #define ComputeT ...

  6. oo修仙之路

    写在前面: 之前听说过oo这门课的威力,计院全体修仙现场的图也被转了不知多少遍,然而自己不亲身经历就不知这门课的难度所在.每次debug时耳边总会想起三国杀里面周瑜的话"挣扎吧,在血和暗的深 ...

  7. ambari2.6.1汉化记录

    1.1测试机 Apache hadoop2.6Apache ambari 2.6.1集群规模:单节点操作系统 CentOS7以下所有操作均在root用户下执行 1.2安装环境 安装Maventar - ...

  8. miniui几个常用知识点汇总

    1.在表格中去除系统自带的序列号,请看代码: function allAndBrief(id) { if(id==1){ grid.set({ columns: [ { type: "ind ...

  9. HP-Socket快速入门:分包、粘包解析

    环境配置 vs2015 windows7 64位 hp-socket 5.0 安装hp-socket 新建控制台项目TelnetServer,打开Nuget管理工具,搜索hp-socket: 安装成功 ...

  10. C#中的var和dynamic

    在理解var和dynamic关键字之前,让我们先了解一下编程语言的类别. C#中有两类编程语言: 静态类型语言类别 动态语言类别 静态类型语言 静态类型语言也被称为强类型语言.所谓强类型语言,通俗的讲 ...