stdarg.h

学习数组的时候遇到一个头文件
#include<stdarg.h>

很好奇这个头文件的作用,就从百度上面摘了下来。

stdarg.h

  stdarg.h是C语言中C标准函式库的标头档,stdarg是由standard(标准) arguments(参数)简化而来,主要目的为让函式能够接收不定量参数。[1] C++的cstdarg标头档中也提供这样的机能;虽然与C的标头档是相容的,但是也有冲突存在。
  不定参数函式(Variadic functions)是stdarg.h内容典型的应用,虽然也可以使用在其他由不定参数函式呼叫的函式(例如,vprintf)。
  宣告不定参数函式
  不定参数函式的参数数量是可变动的,它使用省略号来忽略之后的参数。例如printf函式一般。代表性的宣告为:
  int check(int a, double b, ...);
  不定参数函式最少要有一个命名的参数,所以
  char *wrong(...);
  在C是不被允许的(在C++中,这样的宣告是合理的)。在C,省略符号之前必须要有逗号;在C++,则没有这种强制要求。
  定义不定参数函式
  使用相同的语法来定义:
  long func(char, double, int, ...);
  long func(char a, double b, int c, ...)
  {
  /* ... */
  }
  在旧形式可能会出现较省略的函式定义:
  long func();
  long func(a, b, c, ...)
  char a;
  double b;
  {
  /* ... */
  }
  stdarg.h型态名称 描述 相容
  va_list 用来指向参数 C89
  stdarg.h巨集名称 描述 相容
  va_start 使va_list指向起始的参数 C89
  va_arg 检索参数 C89
  va_end 释放va_list C89
  va_copy 拷贝va_list的内容 C99
  存取参数
  存取未命名的参数,首先必须在不定参数函式中宣告va_list型态的变数。呼叫va_start并传入两个参数:第一个参数为va_list型态的变数,第二个为函式最后一个参数的名称,接着每一呼叫va_arg就会回传下一个参数,va_arg的第一个参数为va_list,第二个参数为回传的型态。最后va_end必须在函式回传前被va_list呼叫(当作参数)。(没有要求要读取完所有参数)
  C99提供额外的巨集,va_copy,它能够复制va_list。而va_copy(va2, va1)意思为拷贝va1到va2。
  没有机制定义该怎么判别传递到函式的参数量或者型态。函式通常需要知道或确定它们变化的方法。共通的惯例包含:
  使用printf或scanf类的格式化字串来嵌入明确指定的型态。
  在不定参数最后的标兵值(sentinel value)。
  总数变数来指明不定参数的数量。
  型别安全性
  有些C工具将C扩充允许编译器检查适当格式化字串及标兵(sentinels)的使用。如果没有这个扩充,编译器通常无从检查传入函式的未命名参数是否为所预期的型态。因此,必须对点做出谨慎的正确性确认,型态没有吻合为未定义行为(Undefined behavior)。举个例,如果传入NULL指标,首先就是不能写入对应到适当指标型态但纯粹NULL的指标。再者考虑预设参数应用到未命名参数。float将会自动的被转换成double?同样的比int(整数)更小容量的参数型态将会被转换成int或者unsigned int?函式所接收到的未命名参数必须预期到会被转换型态。
  例子
  #include <stdio.h>
  #include <stdarg.h>
  void printargs(int arg1, ...) /* 输出所有int型态的参数,直到-1结束 */
  {
  va_list ap;
  int i;
  va_start(ap, arg1);
  for (i = arg1; i != -1; i = va_arg(ap, int))
  printf("%d ", i);
  va_end(ap);
  putchar('\n');
  }
  int main(void)
  {
  printargs(5, 2, 14, 84, 97, 15, 24, 48, -1);
  printargs(84, 51, -1);
  printargs(-1);
  printargs(1, -1);
  return 0;
  }
  这个程式产生输出:
  5 2 14 84 97 15 24 48
  84 51
  1
  varargs.h
  POSIX定义所遗留下的标头档varargs.h,它早在C标准化前就已经开始使用了且提供类似stdarg.h的机能。这个标头档不属于ISO C的一部分。档案定义在单使用者UNIX系统规范(Single UNIX Specification)的第二个版本中,简单的包含所有C89 stdarg.h的机能,除了:不能使用在标准C较新的形式定义;你可以不给予参数(标准C需要最少一个参数);与标准C运作的方法不同,其中一个写成:
  #include <stdarg.h>
  int summate(int n, ...)
  {
  va_list ap;
  int i = 0;
  va_start(ap, n);
  for (; n; n--)
  i += va_arg(ap, int);
  va_end(ap);
  return i;
  }
  或比较旧式的定义:
  #include <stdarg.h>
  int summate(n, ...)
  int n;
  {
  /* ... */
  }
  以此呼叫
  summate(0);
  summate(1, 2);
  summate(4, 9, 2, 3, 2);
  使用varargs.h的函式为:
  #include <varargs.h>
  summate(n, va_alist)
  va_dcl /* 这里没有分号! */
  {
  va_list ap;
  int i = 0;
  va_start(ap);
  for (; n; n--)
  i += va_arg(ap, int);
  va_end(ap);
  return i;
  }
  以及相同的呼叫方法。
  varargs.h因为运作的模式需要旧型态的函式定义。[2]

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值