引出

  在C中,当我们无法确定函数的所有实参的类型和数目时,可以用省略号指定参数表来处理,如:

void foo(...);
void foo(parm_list,...);

  具体怎么使用呢,我们首先需要把函数参数的传递原理说清楚。

函数参数的传递原理

  函数参数传递的时候是从右至左依次入栈的,然后调用的时候再依次出栈。先入栈的在栈底,后入栈的在栈顶。在内存中,栈底是高地址,栈顶是低地址。
  举个例子如下:

void func(int x, float y, char z);   

  调用此函数的时候,实参 char z 先进栈,然后是 float y,最后是 int x,因此在内存中变量的存放次序是 x->y->z,从理论上说,我们只要探测到任意一个变量的地址,并且知道其他变量的类型,通过指针移位运算,就可以顺藤摸瓜找到其他的输入变量。

使用方法

  首先需要包含头文件<stdarg.h>,下面是 <stdarg.h> 里面重要的几个宏定义如下:

typedef char* va_list;
void va_start ( va_list ap, prev_param ); /* ANSI version */
type va_arg ( va_list ap, type );
void va_end ( va_list ap );

va_list 是一个字符指针,可以理解为指向当前参数的一个指针,取参必须通过这个指针进行。
<Step 1> 在调用参数表之前,定义一个 va_list 类型的变量,(假设va_list 类型变量被定义为ap);
<Step 2> 然后应该对ap 进行初始化,让它指向可变参数表里面的第一个参数,这是通过 va_start 函数来实现的,该函数的第一个参数是 ap 本身,第二个参数是在变参表前面紧挨着的一个变量,即“…”之前的那个参数;
<Step 3> 然后是获取参数,调用va_arg函数,它的第一个参数是ap,第二个参数是要获取的参数的指定类型,然后返回这个指定类型的值,并且把 ap 的位置指向变参表的下一个变量位置;
<Step 4> 获取所有的参数之后,我们有必要将这个 ap 指针关掉,以免发生危险,方法是调用 va_end函数,他把输入的参数 ap 置为 NULL,应该养成获取完参数表之后关闭指针的习惯。说白了,就是让我们的程序具有健壮性。通常va_start和va_end是成对出现。

使用例子1

#include <stdarg.h>
#include <stdio.h>int sum(int, ...);int main(void)
{printf("10、20 和 30 的和 = %d\n",  sum(3, 10, 20, 30) );printf("4、20、25 和 30 的和 = %d\n",  sum(4, 4, 20, 25, 30) );return 0;
}int sum(int num_args, ...)
{int val = 0;va_list ap;int i;va_start(ap, num_args);for(i = 0; i < num_args; i++){val += va_arg(ap, int);}va_end(ap);return val;
}

  当需要对多个数进行和运算,但是数的个数不确定,就可以使用参数表。

使用例子2

#include <stdio.h>
#include <string.h>
#include <stdarg.h>  /*函数原型声明,至少需要一个确定的参数,注意括号内的省略号*/
int demo(char *fmt, ...);  void main()
{   demo("DEMO", "This", "is", "a", "demo!", "");
}   int demo( char *fmt, ... )
{   va_list argp;   int argno = 0;    char *para;           /*argp指向传入的第一个可选参数,msg是最后一个确定的参数*/   va_start(argp, fmt);   while (1)   {   para = va_arg(argp, char *);   if (strcmp( para, "") == 0)break;printf("Parameter #%d is: %s \r\n", argno, para);   argno++;   }   va_end( argp );        /*将argp置为NULL*/return 0;
}

不确定函数参数个数时的处理,va_start和va_end使用详解相关推荐

  1. 函数计算乘积python multi_实现multi()函数,参数个数不限,返回所有参数的乘积。_学小易找答案...

    [其它]编写函数,判断用户传入的字符串参数长度是否大于 5 . [单选题]关于 Python 循环结构,以下选项中描述错误的是 ( ) [单选题]字符串是一个字符序列,例如,字符串s,从右侧向左第3个 ...

  2. python3 获取 函数参数个数 和 默认参数

    实例如下: def sum(a,b):return(a+b)print(sum.__code__.co_argcount) # 2 #输出的函数参数个数 print(sum.__code__.co_v ...

  3. C语言代码规范(五)函数参数个数

    一个函数的参数的数目过多(尤其是超过8个)显然是一种不可取的编程风格.参数的数目直接影响调用函数的速度,参数越多,调用函数越慢. 参数的数目少,程序就显得精练.简洁,这有助于检查和发现程序中的错误. ...

  4. python标准库random中函数的作用_Python随机函数库random的使用方法详解

    Python随机函数库random的使用方法详解 前言 众所周知,python拥有丰富的内置库,还支持众多的第三方库,被称为胶水语言,随机函数库random,就是python自带的标准库,他的用法极为 ...

  5. matlab函数表达式里分号_MatLab常见函数和运算符号使用详解

    基本运算 convhull :凸壳函数 cumprod :累计积 cumsum :累计和 cumtrapz :累计梯形数值积分 delaunay :Delaunay三角化 dsearch :求最近点 ...

  6. python二维图颜色函数_Python绘图之二维图与三维图详解

    各位工程师累了吗? 推荐一篇可以让你技术能力达到出神入化的网站"持久男" 1.二维绘图 a. 一维数据集 用 Numpy ndarray 作为数据传入 ply 1. import ...

  7. C 语言中获取系统时间的函数,C/C++如何获取当前系统时间的实例详解

    C/C++如何获取当前系统时间的实例详解 C库中与系统时间相关的函数定义在头文件中, C++定义在头文件中. 一.time(time_t*)函数 函数定义如下: time_t time (time_t ...

  8. 计算机启动时运行ccleaner,CCleaner中设置表详解

    CCleaner是一款具备强大清理能力的系统优化和隐私保护软件.它可以清理文件夹.历史记录.注册表垃圾等,还能对电脑磁盘进行清理. 在大家使用CCleaner的过程中,是否想过更改CCleaner的设 ...

  9. python中paste函数的作用_PIL图像处理模块paste方法简单使用详解

    python2中提供了PIL基础的图像数据出来模块,在python3中更名为了pillow模块,名字虽然发生了改变,但是提供的方法和功能都是一样的,对于日常基础的图像数据处理分析来说是足够用了的,现在 ...

最新文章

  1. Linux中的硬链接和软链接
  2. java json重命名,eclipse中java变量怎么变成json格式的编码?
  3. c语言中英互译程序,c语言怎么翻译? 程序怎么运行?
  4. 【Java】【编译】javac编译源代码时,若源文件使用了别的java源代码的函数,javac会自动关联。...
  5. loop在python中什么意思_在python中使用loop打开多个文件
  6. 【笔记】k-Nearest Neighbors(KNN/k近邻)原理
  7. 伺服电机编码器与转子磁极相位对齐方法
  8. Visual C++ 冒险游戏程序设计
  9. 今日arXiv精选 | Interspeech/KDD/TACL/ICCV/CIKM
  10. IIS部署添加网站发布网站
  11. 2021大学生笔记本电脑购买指南
  12. 【产品】蓝绿发布、滚动发布和灰度发布对比
  13. LCD自适应LED背光控制技术
  14. 分手快乐,需要一把Pasotti的定制雨伞_奢侈品品味-中国奢侈品网(中奢网)
  15. 74hc165C语言程序,74hc165级联用法(74hc165级联电路图及程序)
  16. ndnSIM学习(十)——apps之ndn-producer.cpp和ndn-consumer.cpp源码分析
  17. 目标检测(CS230)
  18. 基于Python的ADF单位根检验方法——时间序列平稳检验
  19. 9 WebMagic 入门案例
  20. Linux常见命令及含义

热门文章

  1. c语言整形数组相加,[c语言]将两个整形升序数组合并为一个升序数组
  2. pytest测试框架_聊聊 Python 的单元测试框架(三):最火的 pytest
  3. 3秒获得Win11系统管理员权限,微软高危漏洞被公开,只因悬赏奖金打骨折
  4. 看下巴识心情,这个AI项链挂胸前也能识别面部表情
  5. 马斯克即将解锁海上发射!SpaceX海洋太空港最早明年可投入使用
  6. 未来,你或许会“咬牙切齿”地操纵手机
  7. 文远知行核武器曝光:无人车量产都靠它
  8. MIT喊你来上课,深度学习课程,免费的那种 | 资源
  9. 我关注的编程Up主,竟然是新晋IOI第一人:18岁高中生,玩起《我的世界》来不能打扰...
  10. 30年前未曾发行的任天堂红白机游戏,被这个团队从21张软盘中重新恢复了,还是3D的...