函数调用 转换控制到函数的机制。
在上面的函数调用中,数27被称为自变量(或实参)。自变量可以使得同一函数在许多不同的值上运行,例如,我们写出像这样一些语句: cout << Cube(b) ; cout << Cube(16) ;
这里是一个函数调用的语法模板:
自变量表列 一种函数互相通讯的机制。
一些函数,像Square 和Cube, 在参数表中有一个自变量,另一些函数,像主函数main, 在参数表中没有自变量。一些函数在参数表中有两个、三个或更多的用逗号分隔的自变量。 带回返回值的函数被使用在表达式中,就像使用变量和常量一样,例如,语句 someInt = Cube(2) 1O;
首先Cube 函数被执行来计算2的立方得到8,然后值8乘以10。注意函数调用比乘运算有更高的优先权。
这里是有关带回返回值函数的几种情况:
? 函数调用是在一个表达式内被使用;它不能作为单独的语句出现。 ? 函数计算出的值(结果)被有效的使用在表达式中。 ? 函数不多不少只返回一个结果。
函数Cube期望被给(或被传送)一个整型int的自变量,若函数调用是 Cube( 6.9 )计算的是6的立方,而不是6.9的立方。
事实上,带回返回值函数的自变量可以是任何合适类型的表达式。在语句 alpha = Cube(int1 int1 + int2 int2);
中,自变量表列中的表达式首先被求值,只是它的结果被传送到函数。例如,如果int1 包含 3 和 int2 包含 5, 上面函数调用传送34 作为自变量到Cube。
函数自变量表列中的表达式甚至可以包含调用函数,例如: alpha = Cube(Square(int1) + Square(int2) ) ; 库函数
为了是编程者的编程更容易,每个C++系统都包含一个标准库——一个大量的预先编写好的实现计算的函数集合。
这里是一些标准库函的少部分样板:
从技术上来讲,表中标记为float应该都是double。这些库函数使用双精度的浮点值来完成它们的工作。但是由于类型的强制,当你传送float值给函数时函数仍能工作。
使用库函数是容易的。首先,你放置一条#include 指令在你程序顶部附近,指定合适的头文件。这条指令引起C++预编译器插入声明到你的程序中给编译器一些有关函数的信息,然后,当你想使用函数时,你就能做这里是一个例子: #include
#include
float alpha ;
float beta ; :
alpha = sqrt(7.3 + fabs(beta)) ;
C++ 标准库函数提供了一打函数为你使用,附录C列出比我们这里提出的多得多选择。
无返回值的函数(void函数)
如果你看了下列函数CalcPay的定义,你就会看见CalcPay 用单词void 的开始而不是用像类型int 或float的单词开始: void CalcPay( . . . ) { : : }
CalcPay 是一个不带回返回值给它的主调者的函数例子,而只是完成一些活动然后返回。 我们称这样的函数为无返回值的函数,或简单地称为void函数。
具有void的函数, 函数调用是独立的、单独的语句。函数main可以这样调用 CalcPay 函数: CalcPay(payRate , hours , wages) ; DoThis(x , y , z) ; DoThat ( ) ;
我们强调调用这两种函数(void 函数和带回返回值函数)的差别: 对带回返回值的函数的调用是出现在一个表达式中,而对void 函数的调用是作为单独语句出现的。 3.7 格式化输出
格式程序的输出意味着控制如何在屏幕或打印机上的视觉效果,在这部分,我们检查如何格式输出值。 整数和串
缺省情况下,连续的整型和串值输出中间是没有空格的,如果变量i, j和 k 分别包含了值15, 2和 6,则语句
cout << \输出字符流 Results: 1526 数字之间没有空格。
为了分开输出值,你能够在数字之间打印一个空格(作为一个字符常量输出): cout <<“Results:” << i << ‘ ‘ << j << ‘ ‘ << k; 这个语句产生的输出为 Results: 15 2 6
如果你希望在项目之间有甚至更多的空格,使用字面串常量空格,像我们在第二章讨论的一样: cout << \这个结果输出是: Results: 15 2 6
控制输出的水平空格的另一种方法是使用控制符。像一个函数一样,一个控制符引起一些行为出现。但也像一个数据对象,一个控制符能够出现在一系列插入操作中间: cout << someInt << endl << someFloat; 控制符只被用于输入和输出语句中。
C++标准库提供了许多控制符,但现在我们只看5个: endl, setw, fixed, showpoint, setprecision.
当我们包含头文件iostream 来执行输入/输出时,endl、 fixed和 showpoint 控制符不受约束,另两个控制符setw 和 setprecision需要我们包含头文件iomanip: #include
cout << setw(5) << someInt;
控制符setw意味着\设置宽度\,setw让我们控制下一个数据项当它输出时应该占据多少个字符位置(setw 只用来格式数字和串,不能用来格式字符数据)。 setw的自变量是一个整型表达式,称为域宽说明; 字符位置组称为域。要输出的下一个数据项被打印成右对齐(为了填满域,字符左边填空格)。 让我们看一些例子,假设两个int 变量已经被赋值如下: ans = 33; num = 7132;
那么下列输出语句产生的输出结果显示在它们的右边。
在(1)中, 每个值被指定占据足够的位置以便有至少一个空格来分开数据值。
在(2)中,由于为每个值指定的域宽正好与值宽度一样,所有的值都在一起,这种输出显然不是很好读的。最好使域宽大于数值所需的最小宽度,以便在值之间流一些空的地方。 在(3)中,为了可读性值之间有额外的空格。 在(4)中,值之间没有空格。
在(5)中,域宽没有ans 值宽,所以域宽自动被扩展,使得空间能容纳所有数字。
设置域宽是一次性的行为,它只保持到紧接着的要输出下一个项目,在这个输出后,域宽复位到0,意味着“域扩展到与它所需要的多少位置一样宽”。在语句 cout << \
中域宽在ans 输出后复位到0,结果,我们得到输出为 Hi 337132 浮点数
你可以像整型数那样为浮点值指定域宽,但是当你指定字符位置数时,你必须记住要考虑小数点。值4.85需要4个输出位置,不是3个。如果x 包含值 4.85, 语句 cout << setw(4) << x << endl << setw(6) << x << endl << setw(3) << x << endl; 产生输出 4.85 4.85 4.85
在第三行,域宽3是不够的,所以域自动扩展以适应数字。 有几个其它的与浮点数输出相关的讨论。
第一,大的浮点值以科学标记法打印出来, 值123456789.5 也许在一些系统上打印像这样 1.23457E+08
你能使用名为fixed控制符来强迫所有后续的浮点输出以小数形式而不是科学标记法输出: cout << fixed << 3.8 * x ;
第二,如果数字只有整数, C++ 不会打印小数点,值95.0 打印为: 95
为了在后续的浮点输出中强迫显示小数点,甚至对于只有整数的浮点数也强迫显示小数点,你可以使用控制符 showpoint:
cout << showpoint << floatVar;
第三,你常想控制小数显示的位数(小数点右边的数字)。如果你的程序假设是打印某种数额上5%销售税, 语句为
cout << \也许输出 Tax is $17.7435
这里,你更想显示的结果是两位小数,为了这样做,使用setprecision 控制符如下: cout << fixed << setprecision(2) << \
所提供的fixed已经被指定,送到setprecision的自变量指定所希望的小数的位数,送到setprecision中的自变量值保留它的影响到所有后续的输出中(直到你用其它的自变量值调用setprecision)。这里是与setw 结合在一起使用setprecision的一些例子:
再就是,如果域宽setw指定太窄,打印位数会扩展到总数据的宽度,可是小数的位数完全由传送到setprecision 的自变量来控制。
下列表总结了我们在这部分讨论的控制符。没有自变量的控制符通过头文件iostream 有效,那些有自变量的控制符需要头文件 iomanip。
setw 只用于数字和串,不能用于字符数据,setw 也只能用于紧接着的下一个输出项,之后域宽复位到0(意味着“只使用所需要的那样多的位数”)。
3.8 另外的string 操作
在这节,我们介绍四个对串的操作函数: length、 size、 find 和 substr。 length 和 size 函数
当length 函数应用到一个串变量时,返回一个无符号整型值,这个整型值等于当前串中字符数,一个对length 函数的调用像这样: myName .length ( )
你指定一个串变量名(这里是myName),然后是一个点,然后再是函数名和自变量表列。 length 函数不需要自变量传送给它,但你仍必须使用一个空自变量表列的括号。Length也是一个有返回值的函数,所以函数调用必须出现在 一个表达式内: string firstName ; string fullName ; firstName = \
cout << firstName.length() << endl; // 打印出 9 fullName = firstName + \
cout << fullName.length() << endl; // 打印出 15
这个表达式, firstName.length( ), 使用一个称为点标记的C++标记 。在变量名firstName和函数名length中间有一个点。如果你忘记使用点标记,写函数调用为 length ( )
你在编译时会得到某些像\的出错信息,编译器认为你试图调用一个普通的函数名为length的函数,而不是与串类型联系在一起的length函数。 firstName.size( )和firstName .length( )返回同样的值。
我们说length 函数返回一个无符号整型值,如果我们想存结果到一个变量len中 ,像在 len = firstName.length( ) ;
中,那么我们应该声明len 为什么样的数据类型?串类型为我们的使用定义了一个size_type的数据类型 :
string firstName ;
string: :size_type len; firstName = \len = firstName.length() ;
由于size_type的定义隐含在串类型定义内,注意我们必须使用有限制的名string:: size_type。 find 函数
find 函数搜索一个串,找出第一次出现的特定子串并返回一个无符号整型值(具有类型string :: size_type)给出搜索的结果,作为自变量传送到函数的子串可以是字面串或一个串表达式。如果 str1 和 str2 具有串类型,下列是有效的函数调用:
str1.find(\
上面每种情况是搜索 str1中指定的子串是否能在它里面被找到,如果能找到,函数返回str1中匹配开始的位置(位置是从0开始,所以一个串的第一个字符位置是位置0,第二个字符位置是 位置1,等等)。对于一个成功的搜索,必须是完全的匹配的,包括完全相同的大写字母。如果子串不能被找到,函数返回一个特殊的值string: : npos , 一个名字常量,意味着“在串内没有位置”(在许多计算机上string :: npos 是类型string:: size_type中最大可能的像4294967295这样的值。这个值适合于“无效位置” ,因为串操作不会让任何串成为这么长)。 给出代码段 string phrase;
string:: size_type position; phrase = \语句
position = phrase .find(\赋给 position 的值为12, 因而语句 position = phrase .find(\
赋给position 的值为 string: : npos ,因为没有匹配的子串。
find 函数的自变量也可能是一个字符值,在这种情况中,find 搜索串中第一次出现的那个字符并且返回它的位置(或string :: npos,如果字符没有被找到) 例如,代码段 string theString;
theString = \cout << theString .find( 'a') ;
输出值为3, 这是theString 串中第一次出现小写字母a 的位置。 下列是一些调用find 函数的例子,假如下列代码段已经被执行: string str1; string str2;
str1 = \str2 = \
注意在第四个例子中,在str1中有两个子串\的拷贝,但find 只返回第一个\的拷贝的位置。 substr 函数
substr 函数返回一个串中的一个特定的子串。假设 myString 具有串类型,这里是一个函数调用的例子: myString .substr(5 ,20)
第一个自变量是一个无符号整型指定串内的一个位置,第二个自变量也是无符号数指定所希望子串的长度。函数返回一段串,这段串从指定位置(第一个自变量)开始持续到第二个自变量给出的字符数为止。 注意substr 不改变myString; 它返回一个新的暂时的串值,这个串值是串的一部分拷贝。下列是一些例子,假设语句