1. 变参函数简单示例

#include <stdarg.h>
#include <stdio.h> int Accumlate(int nr, ...)
{
int i = ;
int result = ;
va_list arg = NULL;
va_start(arg, nr); for(i = ; i < nr; i++)
{
result += va_arg(arg, int);
} va_end(arg); return result;
} int main()
{
printf("%d\n", Accumlate(, ));
printf("%d\n", Accumlate(, , ));
printf("%d\n", Accumlate(, , , )); return ;
}

2. 变参函数的实现原理

#define va_list void*

#define va_start(arg, start) arg = (va_list)(((char*)&(start)) + sizeof(start))

#define va_arg(arg, type) *((type*)arg); arg = (char*)arg + sizeof(type);

#define va_end(arg) arg = 0;

#include <stdio.h>

#define va_list void*

#define va_start(arg, start) arg = (va_list)(((char*)&(start)) + sizeof(start))

#define va_arg(arg, type) *((type*)arg); arg = (char*)arg + sizeof(type);

#define va_end(arg) arg = NULL;

int Accumlate(int nr, ...)
{
int i = ;
int result = ;
va_list arg = NULL;
va_start(arg, nr); for(i = ; i < nr; i++)
{
result += va_arg(arg, int);
} va_end(arg); return result;
} int main()
{
printf("%d\n", Accumlate(, ));
printf("%d\n", Accumlate(, , ));
printf("%d\n", Accumlate(, , , )); return ;
}

3. 关于参数结束标志的问题

① 指定参数个数,如示例代码

② 用固定值(如-1或NULL)表示最后一个参数

③ 用格式化字符串,如printf函数

注:变参函数至少要提供一个参数

C语言变参函数的实现原理的更多相关文章

  1. C语言变参函数/Variadic fucntion

    几个重要的 宏/类型 定义 Macros Defined in header <stdarg.h> va_start enables access to variadic function ...

  2. 深入php内核,从底层c语言剖析php实现原理

    深入php内核,从底层c语言剖析php实现原理 非常好的电子书:http://www.cunmou.com/phpbook/preface.md   这是它的目录: PHP的生命周期 让我们从SAPI ...

  3. C 语言实现多态的原理:函数指针

    C语言实现多态的原理:函数指针 何为函数指针?答案:C Programming Language. 能够查阅下,从原理上来讲,就是一个内存地址.跳过去运行相应的代码段. 既然如此,在运行时决定跳到哪个 ...

  4. 大神是如何学习 Go 语言之 Channel 实现原理精要

    转自: https://mp.weixin.qq.com/s/ElzD2dXWeldYkJmVVY6Djw 作者Draveness Go 语言中的管道 Channel 是一个非常有趣的数据结构,作为语 ...

  5. C语言指针-从底层原理到花式技巧,用图文和代码帮你讲解透彻

    这是道哥的第014篇原创 目录 一.前言 二.变量与指针的本质 1. 内存地址 2. 32位与64位系统 3. 变量 4. 指针变量 5. 操作指针变量 5.1 指针变量自身的值 5.2 获取指针变量 ...

  6. iOS OC语言: Block底层实现原理

    先来简单介绍一下BlockBlock是什么?苹果推荐的类型,效率高,在运行中保存代码.用来封装和保存代码,有点像函数,Block可以在任何时候执行. Block和函数的相似性:(1)可以保存代码(2) ...

  7. C语言编译器 cc 编译原理

    生成一个可执行的文件通常需要经过以下几个步骤: 预处理你的源代码,去掉注释,以及其他技巧性的工作就像在 C 中展开宏. 检查代码的语法看你是否遵守了这个语言的规则.如果没有,编译器会给出 警告. 把源 ...

  8. iOS OC语言: Block底层实现原理 (转载)

    作者:Liwjing 地址:http://www.jianshu.com/users/8df89a9d8380/latest_articles 先来简单介绍一下Block Block是什么? 苹果推荐 ...

  9. C语言变参函数的编写

    1. 引言 一般我们编程的时候,函数中形式参数的数目通常是确定的,在调用时要依次给出与形式参数对应的实际参数.但在某些情况下我 们希望函数的参数个数可以根据需要确定,因此c语言引入可变参数函数.典型的 ...

随机推荐

  1. MSSQL 当前数据库中已存在用户或角色,SQLServer2008,错误15023,

    原因: sql server中“登录”与“用户”的区别,“登录”用于用户身份验证,而数据库“用户”帐户用于数据库访问和权限验证.登录通过安全识别符 (SID) 与用户关联.将数据库恢复到其他服务器时, ...

  2. 恢复oracle的回收站的所有的表

    使用sys as sysdba 进入到sqlplus的控制界面 sqlplus / as sysdba 执行相关的命令,自动生成一个脚本文件 spool d:/a.sql select 'flashb ...

  3. TaikrSpaceShooterStartKit.unitypackage包下载地址

    有好多教程里面没有资源包,现在加密分享给大家 unity4.*  链接: https://pan.baidu.com/s/1XMo2zVpV3ZhkNZKOb6H0yw 密码: tqnt unity5 ...

  4. iOS 地图(添加大头针)

    首先在工程中导入MapKit.framework库文件 #import <UIKit/UIKit.h> @interface AppDelegate : UIResponder <U ...

  5. 删除GHOST中win7桌面IE删不掉的解决办法

    打开Win+R 运行regedit 依次打开: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Deskto ...

  6. C++的运算符重载 (转)

      C++中预定义的运算符的操作对象只能是基本数据类型.但实际上,对于许多用户自定义类型(例如类),也需要类似的运算操作.这时就必须在C++中重新定义这些运算符,赋予已有运算符新的功能,使它能够用于特 ...

  7. WebGoat系列实验Access Control Flaws

    WebGoat系列实验Access Control Flaws Using an Access Control Matrix 在基于角色的访问控制策略中,每个角色都代表了一个访问权限的集合.一个用户可 ...

  8. enum枚举型

    在实际编程中,有些数据的取值往往是有限的,只能是非常少量的整数,并且最好为每个值都取一个名字,以方便在后续代码中使用,比如一个星期只有七天,一年只有十二个月,一个班每周有六门课程等. 以每周七天为例, ...

  9. 关于AJAX异步加载节点无法触发点击事件问题的解决方式

    做练习的过程中遇到一个问题,使用AJAX异步新增一个节点,无法触发点击事件,经过查阅之后知道一个方式,使用JS的委托事件,在此做一个记录. $(document).on('click', '.recr ...

  10. Kotlin第一篇 Hello Kotlin以及简单介绍。

    首先需要一个编译器,我们使用Intellij IDE  https://www.jetbrains.com/idea/download/#section=windows 下载下来安装好. 那么我们就来 ...