实例讲解在C++的函数中变量参数及默认参数的使用

 更新时间:2020年4月25日 17:36  点击:1532

包含变量参数列表的函数
如果函数声明中最后一个成员是省略号 (...),则函数声明可采用数量可变的参数。在这些情况下,C++ 只为显式声明的参数提供类型检查。即使参数的数量和类型是可变的,在需要使函数泛化时也可使用变量参数列表。函数的系列是一个使用变量参数列表的函数的示例。printfargument-declaration-list
包含变量参数的函数
若要访问声明后的参数,请使用包含在标准包含文件 STDARG.H 中的宏(如下所述)。

采用数量可变的参数的函数声明至少需要一个占位符参数(即使不使用它)。如果未提供此占位符参数,则无法访问其余参数。
当 char 类型的参数作为变量参数进行传递时,它们将被转换为 int 类型。同样,当 float 类型的参数作为变量参数进行传递时,它们将被转换为 double 类型。其他类型的参数受常见整型和浮点型提升的限制。

使用参数列表中的省略号 (...) 来声明需要变量列表的函数。使用在 STDARG.H 包含文件中描述的类型与宏来访问变量列表所传递的参数。有关这些宏的详细信息,请参阅 va_arg、va_copy、va_end、va_start。(处于 C 运行时库文档中)。
以下示例演示如何将宏与类型一起使用(在 STDARG.H 中声明):va_listva_endva_argva_start

// variable_argument_lists.cpp
#include <stdio.h>
#include <stdarg.h>

// Declaration, but not definition, of ShowVar.
void ShowVar( char *szTypes, ... );
int main() {
  ShowVar( "fcsi", 32.4f, 'a', "Test string", 4 );
}

// ShowVar takes a format string of the form
//  "ifcs", where each character specifies the
//  type of the argument in that position.
//
// i = int
// f = float
// c = char
// s = string (char *)
//
// Following the format specification is a variable 
// list of arguments. Each argument corresponds to 
// a format character in the format string to which 
// the szTypes parameter points 
void ShowVar( char *szTypes, ... ) {
  va_list vl;
  int i;

  // szTypes is the last argument specified; you must access 
  // all others using the variable-argument macros.
  va_start( vl, szTypes );

  // Step through the list.
  for( i = 0; szTypes[i] != '\0'; ++i ) {
   union Printable_t {
     int   i;
     float  f;
     char  c;
     char  *s;
   } Printable;

   switch( szTypes[i] ) {  // Type to expect.
     case 'i':
      Printable.i = va_arg( vl, int );
      printf_s( "%i\n", Printable.i );
     break;

     case 'f':
       Printable.f = va_arg( vl, double );
       printf_s( "%f\n", Printable.f );
     break;

     case 'c':
       Printable.c = va_arg( vl, char );
       printf_s( "%c\n", Printable.c );
     break;

     case 's':
       Printable.s = va_arg( vl, char * );
       printf_s( "%s\n", Printable.s );
     break;

     default:
     break;
   }
  }
  va_end( vl );
}
//Output: 
// 32.400002
// a
// Test string

上一个示例演示以下重要概念:
在访问任何变量参数前,必须建立一个列表标记作为类型 va_list 的变量。在前面的示例中,该标记称为 vl。
使用 va_arg 宏访问各个参数。必须告知 va_arg 宏要检索的参数的类型,以便它可以从堆栈中传输正确的字节数。如果为 va_arg 指定的大小的类型与通过调用程序提供的类型不同,则结果是不可预知的。
应将使用 va_arg 宏获取的结果显式强制转换为所需类型。
必须调用宏以终止可变参数处理。va_end


默认参数
在许多情况下,函数具有不常使用的参数,因为使用默认值便已足够。为了解决此问题,默认参数工具允许为函数仅指定在给定调用中有意义的参数。为了阐释此概念,请考虑函数重载中所示的示例。

// Prototype three print functions.
int print( char *s );         // Print a string.
int print( double dvalue );      // Print a double.
int print( double dvalue, int prec ); // Print a double with a
// given precision.

在许多应用程序中,可为 prec 提供合理的默认值,从而消除对两个函数的需求:

// Prototype two print functions.
int print( char *s );          // Print a string.
int print( double dvalue, int prec=2 ); // Print a double with a
// given precision.

略微更改了 print 函数的实现以反映类型 double 仅存在一个此类函数这一事实:

// default_arguments.cpp
// compile with: /EHsc /c

// Print a double in specified precision.
// Positive numbers for precision indicate how many digits
// precision after the decimal point to show. Negative
// numbers for precision indicate where to round the number
// to the left of the decimal point.

#include <iostream>
#include <math.h>
using namespace std;

int print( double dvalue, int prec ) {
  // Use table-lookup for rounding/truncation.
  static const double rgPow10[] = { 
   10E-7, 10E-6, 10E-5, 10E-4, 10E-3, 10E-2, 10E-1, 10E0,
     10E1, 10E2, 10E3, 10E4, 10E5, 10E6
  };
  const int iPowZero = 6;
  // If precision out of range, just print the number.
  if( prec >= -6 && prec <= 7 )
   // Scale, truncate, then rescale.
   dvalue = floor( dvalue / rgPow10[iPowZero - prec] ) *
   rgPow10[iPowZero - prec];
  cout << dvalue << endl;
  return cout.good();
}

若要调用新的 print 函数,请使用如下代码:

print( d );  // Precision of 2 supplied by default argument.
print( d, 0 ); // Override default argument to achieve other
// results.

使用默认参数时,请注意以下几点:
默认参数仅在其中省略了尾随参数的函数调用中使用 - 它们必须是最后的参数。因此,以下代码是非法的:

int print( double dvalue = 0.0, int prec );

默认参数不能在以后的声明中重新定义,即使重新定义的参数与原始参数相同也是如此。因此,以下代码将生成错误:

// Prototype for print function.
int print( double dvalue, int prec = 2 );

...

// Definition for print function.
int print( double dvalue, int prec = 2 )
{
...
}

此代码的问题在于定义中的函数声明重新定义了 prec 的默认参数。
以后的声明可添加额外的默认参数。
可为指向函数的指针提供默认参数。例如:

int (*pShowIntVal)( int i = 0 );

[!--infotagslink--]

相关文章

  • php正确禁用eval函数与误区介绍

    eval函数在php中是一个函数并不是系统组件函数,我们在php.ini中的disable_functions是无法禁止它的,因这他不是一个php_function哦。 eval()针对php安全来说具有很...2016-11-25
  • php中eval()函数操作数组的方法

    在php中eval是一个函数并且不能直接禁用了,但eval函数又相当的危险了经常会出现一些问题了,今天我们就一起来看看eval函数对数组的操作 例子, <?php $data="array...2016-11-25
  • C++ STL标准库std::vector的使用详解

    vector是表示可以改变大小的数组的序列容器,本文主要介绍了C++STL标准库std::vector的使用详解,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2022-03-06
  • Python astype(np.float)函数使用方法解析

    这篇文章主要介绍了Python astype(np.float)函数使用方法解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2020-06-08
  • C++中取余运算的实现

    这篇文章主要介绍了C++中取余运算的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-02-23
  • Python中的imread()函数用法说明

    这篇文章主要介绍了Python中的imread()函数用法说明,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-03-16
  • 详解C++ string常用截取字符串方法

    这篇文章主要介绍了C++ string常用截取字符串方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-04-25
  • C++调用C#的DLL程序实现方法

    本文通过例子,讲述了C++调用C#的DLL程序的方法,作出了以下总结,下面就让我们一起来学习吧。...2020-06-25
  • C# 中如何取绝对值函数

    本文主要介绍了C# 中取绝对值的函数。具有很好的参考价值。下面跟着小编一起来看下吧...2020-06-25
  • C#学习笔记- 随机函数Random()的用法详解

    下面小编就为大家带来一篇C#学习笔记- 随机函数Random()的用法详解。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧...2020-06-25
  • C++中四种加密算法之AES源代码

    本篇文章主要介绍了C++中四种加密算法之AES源代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。...2020-04-25
  • C++ 整数拆分方法详解

    整数拆分,指把一个整数分解成若干个整数的和。本文重点给大家介绍C++ 整数拆分方法详解,非常不错,感兴趣的朋友一起学习吧...2020-04-25
  • 金额阿拉伯数字转换为中文的自定义函数

    CREATE FUNCTION ChangeBigSmall (@ChangeMoney money) RETURNS VarChar(100) AS BEGIN Declare @String1 char(20) Declare @String2 char...2016-11-25
  • C++中 Sort函数详细解析

    这篇文章主要介绍了C++中Sort函数详细解析,sort函数是algorithm库下的一个函数,sort函数是不稳定的,即大小相同的元素在排序后相对顺序可能发生改变...2022-08-18
  • Android开发中findViewById()函数用法与简化

    findViewById方法在android开发中是获取页面控件的值了,有没有发现我们一个页面控件多了会反复研究写findViewById呢,下面我们一起来看它的简化方法。 Android中Fin...2016-09-20
  • PHP用strstr()函数阻止垃圾评论(通过判断a标记)

    strstr() 函数搜索一个字符串在另一个字符串中的第一次出现。该函数返回字符串的其余部分(从匹配点)。如果未找到所搜索的字符串,则返回 false。语法:strstr(string,search)参数string,必需。规定被搜索的字符串。 参数sea...2013-10-04
  • C++万能库头文件在vs中的安装步骤(图文)

    这篇文章主要介绍了C++万能库头文件在vs中的安装步骤(图文),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-02-23
  • PHP函数分享之curl方式取得数据、模拟登陆、POST数据

    废话不多说直接上代码复制代码 代码如下:/********************** curl 系列 ***********************///直接通过curl方式取得数据(包含POST、HEADER等)/* * $url: 如果非数组,则为http;如是数组,则为https * $header:...2014-06-07
  • php中的foreach函数的2种用法

    Foreach 函数(PHP4/PHP5)foreach 语法结构提供了遍历数组的简单方式。foreach 仅能够应用于数组和对象,如果尝试应用于其他数据类型的变量,或者未初始化的变量将发出错误信息。...2013-09-28
  • C语言中free函数的使用详解

    free函数是释放之前某一次malloc函数申请的空间,而且只是释放空间,并不改变指针的值。下面我们就来详细探讨下...2020-04-25