【Just For Fun】

本系列纯粹娱乐、研究用。一些旁门左道的东西。
事实上可能完全没用。 (๑•̀ω•́๑)

對於可变参数函数、可变参数宏 __VA_ARGS__
我曾經有在另一些地方寫過,搬過來一下。

▌可变参数函数:

需要 #include <stdarg.h>
包括一个类型,四个巨集函数:

类型: va_list ,用来储存巨集va_arg()与巨集va_end()所需资讯
巨集函数:va_start(), va_​​arg(), va_​​end(), va_​​copy()

  • va_list
  • va_start()
  • va_arg()
  • va_end()
  • va_copy()

除了 va_copy() 是 C99 外,其余都是相容于 C89 。

___

▌用法例子:

int sum(int num, ...){va_list args;va_start(args, num);int sum = 0;for(int i = 0; i < num; i++){sum += va_arg(args, int);}va_end(args);return sum;
}

先声明一个 va_list 类型的变量,

va_start() 有两个参数:
第一个是 va_list 类型的变量,
第二个是 可变参数 ... 的前一个的变量名,这里是 num

va_arg() 用于获得额外参数的数值,同样有两个参数:
第一个也是 va_list 类型的变量,
第二个是 载入的参数类型。

注意 载入的参数类型 不可为:

  • char、signed char、unsigned char
  • short、unsigned short
  • signed short、short int、signed short int、unsigned short int
  • float

會有默认参数提升(default argument promotions)

  • float类型的实际参数将提升到double
  • char、short和相应的signedunsigned类型的实际参数提升到int
  • 如果int不能存储原值,则提升到unsigned int

可参看 C语言可变长参数函数与默认参数提升

最后使用 va_end() ,像 fclose() 一样把可变参数关掉。
一个参数,va_list 类型的变量。

可变参数函数的详细实现及原理可参看 可变参数函数详解 - clover_toeic - 博客园
和知乎上其他人的另一篇文章 C语言中可变参数函数实现原理

___

▌可变参数宏 __VA_ARGS__

由 C99 引入,

声明语法类似于可变参数函数:逗号后面三个句点"...",表示一个或多个参数。
但常见编译器也允许传递0个参数。
宏扩展时使用特殊标识符__VA_ARGS__表示所传递的参数的替换。
没办法访问可变参数列表内的单个参数,也不能获知多少个参数被传递。

例子:

#define foo(f, ...) printf(f, __VA_ARGS__)

foo("%d%d", x, y); 等价 printf("%d%d", x, y);
接收了两个额外参数。

注意 没办法访问可变参数列表内的单个参数,也不能获知多少个参数被传递。
所以不能够像可变参数函数一样,
以「简单直观」的方法去实现可变参数的 sum()

___

▌额外的逗号:

若果额外参数的数目为 0 ,即 foo("123");
会被展开为 printf("123",) ,这里出现了一个额外的逗号。

可把 __VA_ARGS__ 改为 ##__VA_ARGS__
去提示编译器,会自动把逗号去除。

我记得这是编译器扩展。如果不想用编译器扩展,可以看看:
c - Standard alternative to GCC's ##__VA_ARGS__ trick? - Stack Overflow
下面有一个丧心病狂的答案。

Visual C++ 貌似不用提醒也会自动去除。

Visual Studio 貌似限定了不能直接使用,(我不确定)
需要在第二次展开宏时才會生效,所以我了封裝一個:

#define eatComma(...) ,##__VA_ARGS__

來給 VS 用。

___

▌参考资料:

stdarg.h - 维基百科,自由的百科全书
可变参数函数详解 - clover_toeic - 博客园
可变参数宏 - 维基百科,自由的百科全书
C语言可变参数宏定义方法 - 做一个有技术追求的人 - CSDN博客
__VA_ARGS__ 与 ## 小档案 变数是否存在 去除逗号 , @ CC :: 随意窝 Xuite日志
microsoft Variadic 巨集

___

原文網址(作者是我):2019 iT 邦幫忙鐵人賽,Day 22:重溫 可變參數函數、可變參數宏 __VA_ARGS__

大约半年前了,不知道有没有错,欢迎指正。

___

【Just For Fun】俺 是 目 录 !

___

下一篇:【Just For Fun】C - 宏开发 - 选取第 n 项参数、按照参数数目展开不同的宏、缺陷

#{}不自动改参数类型_【Just For Fun】C - 可变参数函数、可变参数宏 __VA_ARGS__、额外的逗号相关推荐

  1. functools.partial()==>预先设置参数,使得之后调用的时候,减少函数的参数

    import functoolsdef add(a):print(a + 1)add(2) #输出3newAdd = functools.partial(add,2)newAdd() #输出3 首先大 ...

  2. c2665 “initgraph”: 2 个重载中没有一个可以转换所有参数类型_一个使用延迟候选项生成的用于自动化程序修复方法的工具...

    论文:Jinru Hua, Mengshi Zhang, Kaiyuan Wang, and Sarfraz Khurshid. 2018. SketchFix: A Tool for Automat ...

  3. 两种参数类型_深入理解Java中方法的参数传递机制

    形参和实参 我们知道,在Java中定义方法时,是可以定义参数的,比如: public static void main(String[] args){ } 这里的args就是一个字符串数组类型的参数. ...

  4. c2665 “initgraph”: 2 个重载中没有一个可以转换所有参数类型_Python 命令行之旅:深入 click 之参数篇...

    作者:HelloGitHub-Prodesire 文中涉及的示例代码,已同步更新到 HelloGitHub-Team 仓库 一.前言 在上一篇文章中,我们初步掌握了 click 的简单用法,并了解到它 ...

  5. c 语言重载参数类型不同重载和,C++基础学习之函数重载的简单介绍

    前言 我们在平时写代码中会用到几个函数但是他们的实现功能相同,但是有些细节却不同.例如:交换两个数的值其中包括(int, float,char,double)这些个类型.在C语言中我们是利用不同的函数 ...

  6. 众辰变频器参数设定_电工知识:变频器使用方法设定功能参数的方法

    电工知识:变频器使用方法,设定功能参数的方法 电工知识:变频器使用方法,设定功能参数的方法1.基本参数的设置1)按"MENU"键,控制盘显示屏出现"-99-"字 ...

  7. python函数作为参数例题_笨办法学Python 习题 19: 函数和变量

    函数这个概念也许承载了太多的信息量,不过别担心.只要坚持做这些练习,对照上个练习中的检查点检查一遍这次的联系,你最终会明白这些内容的. 有一个你可能没有注意到的细节,我们现在强调一下:函数里边的变量和 ...

  8. 调用jsapi缺少参数appid_【Python学习笔记】18、函数的参数关键字参数

    可变参数允许你传入0个或任意个参数,这些可变参数在函数调用时自动组装为一个tuple.而关键字参数允许你传入0个或任意个含参数名的参数,这些关键字参数在函数内部自动组装为一个dict.请看示例: de ...

  9. #{}不自动改参数类型_我是干流动补胎的,想让我的柴油机气泵自动打气,怎么改装。谢谢。...

    展开全部 买一个启动系统来 这个系统有源自带电瓶的,也有启2113动电机和启动模5261块的,怎么4102划算怎么去改,改1653装可以让柴油机实现全自动控制,低气压10公斤柴油机自动点火启动,高气压 ...

最新文章

  1. xcode编辑时闪退的问题解决
  2. 安装MariaDB和Apache
  3. 基本概念—机器学习ML与深度学习DL
  4. Python3.6全栈开发实例[005]
  5. 交换机的基本配置实验报告_无线网络设计配置即实验报告
  6. perl6检测网站CMS脚本(测试代码)
  7. linux下php安装
  8. 【Scala】镜像网站下载,速度直接起飞
  9. MD5加密算法(C语言实现,已编译,亲试可用~)
  10. CSS 3 动画 实现图片动态切换
  11. ASP.net 2.0 中 WebResource.axd 管理资源的一些知识点
  12. python做一段有意思的代码_Python爬虫入门有意思的小长代码
  13. leetcode 376. 摆动序列(三种解法)
  14. 2020年了,还不懂数据挖掘?数据挖掘工具有哪些?
  15. android graphics2d,Graphics2D的drawString之不带颜色的字体
  16. Codeforces Round #499 (Div. 2) : C. Fly
  17. Bear Rallies Turn Market Into a Circus
  18. iWO联通3G详单及套餐使用情况查询工具)更新至v0.8.3
  19. 7-4 森森旅游 (20 分)
  20. 华为linux改ip地址,ubuntu9.10校园网上网配置详细教程(华为h3c,mac地址绑定)

热门文章

  1. 太敢说了,自动化测试如果这么自学,培训班都得倒闭,直接省去上万元的学费
  2. stopwatch java_StopWatch简单了解
  3. nginx之rewrite规则未加引号导致检查nginx语法报错
  4. allure与pytest
  5. 可自管理的分布式工作流引擎的设计与实现
  6. thunderbird with exchange 14.04
  7. 百度超级链成为首个捐赠给开放原子开源基金会的项目
  8. ffmpeg 基本命令行
  9. 生成 小程序 URL Scheme
  10. python博客园_python3 模拟博客园登录