【C/C++开发】C语言实现函数可变参数
函数原型: int printf(const char *format[,argument]...)
返 回 值: 成功则返回实际输出的字符数,失败返回-1.
函数说明:
在printf()函数中,format后面的参数个数不确定,且类型也不确定,这些参数都存放在栈内.调用printf()函数时,根据format里的格式("%d %f...")依次将栈里参数取出.而取出动作要用到va_arg、va_end、va_start这三个宏定义,再加上va_list.
(1)va_list事实上是一char *类型,即:
typedef char* va_list;
(2)三个宏定义:
#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,type) ( *(type *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )
#define va_end(ap) ( ap = (va_list)0 )
【attention】C语言中可变参数的原理---printf()函数
int printf(const char* format,...);
使用过C语言的人所再熟悉不过的printf函数原型,它的参数中就有固定参数format和可变参数(用”…”表示).而程序员又可以用各种方式来调用printf,如:
printf("%d ",value);
printf("%s ",str);
printf("the number is %d,string is:%s ",value,str);
可以看出,该函数的参数格式不固定,参数类型不固定.在C语言中使用宏来处理这些可变参数.这些宏看起来很复杂,其实原理挺简单,即根据参数入栈的特点从最靠近第一个可变参数的固定参数开始,依次获取每个可变参数的地址.
(1)宏va_start
通过该宏定义可以获取到可变参数表的首地址,并将该地址赋给指针ap.
(2)宏va_arg
通过该宏定义可以获取当前ap所指向的可变参数,并将指针ap指向下一个可变参数.注意,该宏的第二个参数为类型.
(3)宏va_end
通过该宏定义可以结束可变参数的获取.
程序员通过这三个宏定义就可以实现对可变参数的处理.例如:
#include <stdio.h>
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,type) ( *(type *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )
#define va_end(ap) ( ap = (va_list)0 )
int cal_val(int c, ...)
{
int sum = c;
va_list ap; //声明指向char型的指针
va_start(ap,c); //获取可变参数列表的首地址,并赋给指针ap
c = va_arg(ap,int); //从可变参数列表中获取到第一个参数(返回值即为参数)
while(0 != c)
{
sum += c;
c = va_arg(ap,int); //循环的从可变参数列表中获取到参数(返回值即为参数)
}
va_end(ap); //结束从可变参数列表中获取参数
return sum;
}
int main(int argc, char* argv[])
{
int value1;
value1 = cal_val(1,2,3,4,5,6,7,8,9,0);
printf("value1=%d/n",value1);
value2 = cal_val(6,7,8,9,0);
printf("value2=%d/n",value2);
return 0;
}
【C/C++开发】C语言实现函数可变参数的更多相关文章
- C语言中函数可变参数解析
大多数时候,函数中形式参数的数目通常是确定的,在调用时要依次给出与形式参数对应的所有实际参数.但在某些情况下希望函数的参数个数可以根据需要确定.典型的例子有 大家熟悉的函数printf().scanf ...
- C语言之函数可变参数
先上一段代码: #include<cstdarg> #include<iostream> #include<string> using namespace std; ...
- C语言函数可变参数列表
C语言允许使用可变参数列表,我们常用的printf函数即为可变参数函数,C标准库提供了stdarg.h为我们提供了这方面支持:该头文件提供了一些类型和宏来支持可变参数列表,包括类型va_list,宏v ...
- C 函数可变参数
C 函数可变参数 C 语言中用 ... 表示可变参数,例如: void fun(int x ...) 头文件 cstdarg.h 中包含可变参数类型va_list和处理可变参数的三个宏: va_lis ...
- C语言中的可变参数-printf的实现原理
C语言中的可变参数-printf的实现原理 在C/C++中,对函数参数的扫描是从后向前的.C/C++的函数参数是通过压入堆栈的方式来给函数传参数的(堆栈是一种先进后出的数据结构),最先压入的参数最后出 ...
- c#编程基础之函数可变参数
可变参数:int sum (params int[] values)int sum (string name,params int[] values) 注意:params参数必须是形参表中的最后一个参 ...
- PHP函数可变参数列表的具体实现方法介绍
PHP函数可变参数列表可以通过_get_args().func_num_args().func_get_arg()这三个函数来实现.我们下面就对此做了详细的介绍. AD:2014WOT全球软件技术峰会 ...
- Python函数可变参数*args及**kwargs详解
初学Python的同学们看到代码中类似func(*args, **kwargs)这样的函数参数定义时,经常感到一头雾水. 下面通过一个简单的例子来详细解释下Python函数可变参数*args及**kw ...
- C语言中的可变参数函数的浅析(以Arm 程序中的printf()函数实现为例) .
我们在C语言编程中会遇到一些参数个数可变的函数,一般人对它的实现不理解.例如Printf(): Printf()函数是C语言中非常常用的一个典型的变参数函数,它 的原型为: int printf( c ...
随机推荐
- I9300 国行联通定制修复手记
同事拿来个I9300给我修,说是打不了电话,试了一下,打电话的时候会提示“网络未注册”,于是果断找了个国行的4.1.2五件套刷砖.5分钟后,刷机成功,开机拨号,依旧是这个问题,怎么回事呢?上百度一查, ...
- (17)打鸡儿教你Vue.js
vue-router <a class="list-group-item" v-link="{ path: '/home'}">Home</a ...
- C语言实现多线程排序
#include <stdio.h> #include <pthread.h> #include <stdlib.h> #include <string.h& ...
- [系统]win10远程桌面其他电脑出现如下错误,由于数据加密错误,这个会话讲结束,请重新连接到远程计算机
win10远程桌面其他电脑出现如下错误,由于数据加密错误,这个会话讲结束,请重新连接到远程计算机 这可能是由于credssp加密oracle修正的错误 HKEY_LOCAL_MACHINE\SOFTW ...
- vue + .net core 项目,源码在GitHub 希望对大家有所帮助
一. github UI库 : iview 前端部分 vue .net core + DI + EF(dbfirst) 后端API 部分 .Net Core 二. 往期相关博客 SqlServer 获 ...
- Node.js之文件下载
Node.js之文件下载,主要最近解决我的一个需求. 需求描述:如何将腾讯云上传的文件存储到本地某个目录下,如果用js来实现,纯JavaScript没有这样的功能(也许有),正好我这个项目用node. ...
- [String]两个右补空格使字符串达到固定长度的函数 来自网上 请君自取
代码: package fixsizestring; public class TestClass { public static void main(String[] args) { for(int ...
- 扩展和嵌入 Python 解释器 用 C 或 C++ 编写模块以使用新模块来扩展 Python 解释器的功能 定义新的函数\对象类型\方法。 将 Python 解释器嵌入到另一个应用程序中
// https://python3-cookbook.readthedocs.io/zh_CN/latest/c15/p02_write_simple_c_extension_module.html ...
- MiniDao & Freemarker & include
minidao include - 国内版 Binghttps://cn.bing.com/search?q=minidao+include&qs=n&form=QBRE&sp ...
- 目标检测标注工具labelImg安装及使用
目标检测中,原始图片的标注过程是非常重要的,它的作用是在原始图像中标注目标物体位置并对每张图片生成相应的xml文件表示目标标准框的位置.本文介绍一款使用方便且能够标注多类别并能直接生成xml文件的标注 ...