| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> C++知识库 -> 【C语言库函数】可变参数 va_start、va_arg、va_end、va_list、stdarg.h 库详解 -> 正文阅读 |
|
[C++知识库]【C语言库函数】可变参数 va_start、va_arg、va_end、va_list、stdarg.h 库详解 |
可变参数详解
让我们再来看一眼
可变参数与 stdarg.h 库首先我们来看看 库变量下面是头文件
库宏下面是头文件 stdarg.h 中定义的宏:
注意:以上的所有操作,只能从头到尾顺序访问后面的可变参数,可以暂停,但不能反向读取 库实现
如果将其转换成函数则是
可变参数的存储与实现以下文字引用自博客 可变参数函数详解 C调用约定下可使用va_list系列变参宏实现变参函数,此处va意为variable-argument(可变参数)。 典型用法如下:
变参宏根据堆栈生长方向和参数入栈特点,从最靠近第一个可变参数的固定参数开始,依次获取每个可变参数的地址。 变参宏的定义和实现因操作系统、硬件平台及编译器而异(但原理相似)。 下面这四小段引用自 C语言中函数参数入栈的顺序 C程序栈底为高地址,栈顶为低地址,函数参数入栈顺序的确是从右至左的。可到底为什么呢?查了一直些文献得知,参数入栈顺序是和具体编译器实现相关的。比如,Pascal语言中参数就是从左到右入栈的,有些语言中还可以通过修饰符进行指定,如Visual C++.即然两种方式都可以,为什么C语言要选择从右至左呢? 进一步发现,Pascal语言不支持可变长参数,而C语言支持这种特色,正是这个原因使得C语言函数参数入栈顺序为从右至左。具体原因为:C方式参数入栈顺序(从右至左)的好处就是可以动态变化参数个数。通过栈堆分析可知,自左向右的入栈方式,最前面的参数被压在栈底。除非知道参数个数,否则是无法通过栈指针的相对位移求得最左边的参数。这样就变成了左边参数的个数不确定,正好和动态参数个数的方向相反。 因此,C语言函数参数采用自右向左的入栈顺序,主要原因是为了支持可变长参数形式。换句话说,如果不支持这个特色,C语言完全和Pascal一样,采用自左向右的参数入栈方式。 System V Unix在 两种宏并不兼容,为便于程序移植通常采用ANSI C定义。 gcc编译器使用内置宏间接实现变参宏,如 x86平台VC6.0编译器中,
各宏的含义如下:
#define _INTSIZEOF(n) ((sizeof(n) + x) & ~(x))x = sizeof(int) - 1 = 3 = 0b’0000 0000 0000 0011~x = 0b’1111 1111 1111 1100 一个数与(~x)相与的结果是sizeof(int)的倍数,即_INTSIZEOF(n)将n圆整为sizeof(int)的倍数。
下图给出基于变参宏的可变参数在堆栈中的分布: 变参宏无法智能识别可变参数的数目和类型,因此实现变参函数时需自行判断可变参数的数目和类型。 前者可显式提供变参数目或设定遍历结束条件(如-1、’\0’或回车符等)。 后者可显式提供变参类型枚举值,或在固定参数中包含足够的类型信息(如printf函数通过分析format字符串即可确定各变参类型),甚至主调函数和被调函数可约定变参的类型组织等。 都看到这里了,如果有帮助,点个赞👍👍👍再走呗! |
|
C++知识库 最新文章 |
【C++】友元、嵌套类、异常、RTTI、类型转换 |
通讯录的思路与实现(C语言) |
C++PrimerPlus 第七章 函数-C++的编程模块( |
Problem C: 算法9-9~9-12:平衡二叉树的基本 |
MSVC C++ UTF-8编程 |
C++进阶 多态原理 |
简单string类c++实现 |
我的年度总结 |
【C语言】以深厚地基筑伟岸高楼-基础篇(六 |
c语言常见错误合集 |
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/23 20:44:46- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |