缺省实参

 缺省实参
缺省实参是一种虽然并不普遍但在多数情况下仍然适用的实参值缺省实参使程序员
从函数接口的每个小细节中解脱出来
函数可以用参数表中的初始化语法为一个或多个参数指定缺省实参例如假设一个函
数创建并初始化一个二维字符数组以便模拟终端显示器则我们可以为屏幕的高宽和背景
字符提供缺省实参
char *screenInit( int height = 24, int width = 80,
char background = ' ' );
调用包含缺省实参的函数时我们可以也可以不为该参数提供实参如果提供了实
参则它将覆盖缺省的实参值否则函数将使用缺省实参值下面的screenInit()调用都是
正确的
char *cursor;
// 等价于 screenInit(24,80, ' ')
cursor = screenInit();
// 等价于 screenInit(66, 88, ' ')
cursor = screenInit(66);
// 等价于 screenInit(66, 256, ' ')
cursor = screenInit(66, 256);
cursor = screenInit(66, 256, '#');
函数调用的实参按位置解析缺省实参只能用来替换函数调用缺少的尾部tailing 实
参例如我们不可能为background 提供字符值作为实参而不为height 和width 提供实参
// 等价于 screenInit('<<', 80, ' ')
cursor = screenInit('<<");
// 错误, 不等价于 screenInit(24,80,'<<')
cursor = screenInit( , , '<<');
设计带有缺省实参函数的部分工作就是排列参数表中的参数使最可能取用户指定值的
参数先出现而最可能使用缺省实参的参数出现在后面在screenInit()的设计假设中可能
是通过经验得出height 最可能由用户来提供
函数声明可以为全部或部分参数指定缺省实参在左边参数的任何缺省实参被提供之
前最右边未初始化参数必须被提供缺省实参这是由于函数调用的实参是按照位置来解析

// 错误: 在指定height 之前, width 必须有一个缺省实参
char *screenInit( int height = 24, int width,
char background = ' ' );
一个参数只能在一个文件中被指定一次缺省实参例如下列语句是错误的
// ff.h
294 第七章 函数
int ff( int = 0 );
// ff.C
#include "ff.h"
int ff( int i = 0 ) { ... } // error
习惯上缺省实参在公共头文件包含的函数声明中指定而不是在函数定义中如果缺
省实参在函数定义的参数表中提供则缺省实参只能用在包含该函数定义的文本文件的函数
调用中
函数后继的声明中可以指定其他缺省实参——一种对特定应用定制通用函数的有用方
法UNIX 系统函数chmod()改变文件的保护级别它的函数声明在系统头文件<cstdlib>中
声明如下
int chmod( char *filePath, int protMode );
protMode 表示文件保护模式filePath 表示文件名字和路径位置如果一个特殊的应用
总是将文件的保护模式改变成只读模式read-only 那么我们不用每次都指明它可以重
新声明chmod()缺省地提供该值
#include <cstdlib>
int chmod( char *filepath, int protMode=0444 );
已知下列在头文件ff.h 中声明的函数声明
int ff( int a, int b, int c = 0 ); // ff.h
怎样重新声明ff() 来把缺省实参提供给b 下列语句是错误的因为它重新指定了c 的
缺省实参
#include "ff.h"
int ff( int a, int b = 0, int c = 0 ); // 错误
下列看起来错误的重新声明实际上是正确的
#include "ff.h"
int ff( int a, int b = 0, int c ); // ok
在ff()的重新声明中b 是没有缺省实参的最右边参数因此缺省实参必须从最右边位
置开始赋值的规则没有被打破实际上我们可以再次声明ff()为
#include "ff.h"
int ff( int a, int b = 0, int c ); // ok
int ff( int a = 0, int b, int c ); // ok
缺省实参不一定必须是常量表达式可以使用任意表达式例如
int aDefault();
int bDefault( int );
int cDefault( double = 7.8 );
int glob;
int ff( int a = aDefault(),
int b = bDefault( glob ),
295 第七章 函数
int c = cDefault() );
当缺省实参是一个表达式时在函数被调用时该表达式被求值例如每次不带第三个
实参调用ff()时编译器都会调用cDefault()为c 获取一个值
7.3.6 省略号ellipsis
有时候我们无法列出传递给函数的所有实参的类型和数目在这种情况下我们可以用
省略号... 指定函数参数表
省略号挂起类型检查机制它们的出现告知编译器当函数被调用时可以有0 个或多
个实参而实参的类型未知省略号有下列两种形式
void foo( parm_list, ... );
void foo( ... );
第一种形式为特定数目的函数参数提供了声明在这种情况下当函数被调用时对于
与显式声明的参数相对应的实参进行类型检查而对于与省略号对应的实参则挂起类型检查
在第一种形式中参数声明后面的逗号是可选的
标准C 库输出函数printf()就是一个必须使用省略号的例子printf()的第一个参数总是C
风格字符串
int printf( const char* ... );
这要求printf()的每次调用都必须传递第一个const char*型的实参在printf()的调用中
字符串后面是否有其他实参由第一个被称作格式字符串的实参所决定在格式字符串中由
%开头的元字符表示其他实参的存在例如如下调用
printf( "hello, world/n" );
有一个字符串实参但是如下调用
printf( "hello, %s/n", userName );
有两个实参%表明需要第二个实参s 表明该实参的类型是一个字符串
大多数带有省略号的函数都利用显式声明的参数中的一些信息来获取函数调用中提供
的其他可选实参的类型和数目同此带有省略号的第一种形式的函数声明最常使用
注意下列两个声明并不等价
void f();
void f( ... );
在第一个实例中f()被声明为不接受任何参数的函数在第二个中f()被声明为一个要
求0 个或多个实参的函数如下的调用
f( someValue );
f( cnt, a, b, c );
只对第二个声明是合法的而如下调用
f();
可用来调用第一个或第二个函数

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值