T t;
t=*x; *x=*y; *y=t; //“*x”表示取变量 x 的内容(地址)的内容
}
void main() {
int a=1, b=2;
double c=100.55, d=200.11;
char e='A', f='B';
cout<<"a="<<a<<" b="<<b<<endl;
swap(&a,&b);
cout<<"a="<<a<<" b="<<b<<endl;
cout<<"c="<<c<<" d="<<d<<endl;
swap(&c,&d);
cout<<"c="<<c<<" d="<<d<<endl;
cout<<"e="<<e<<" f="<<f<<endl;
swap(&e,&f);
cout<<"e="<<e<<" f="<<f<<endl;
}
程序的运行结果如下:
例 4.19 定义了一个函数模板 swap,有一个模板参数 T。主函数中使用了三个模板函数,
它们分别以 int 型、double 型和 char 型替换模板参数 T。
要注意的是,例中的函数参数使用传地址参数形式,另外,swap 函数的函数名前使用了 void 型,通常情况下,其类型应该是函数值要求的类型,当然可以是模板参数的类型。
4.7 C++常用系统函数
C++编译系统提供了几百个函数供编程用户使用。 本节将介绍一些常用的系统函数的使用 方法。
使用系统函数要注意以下两点:
(1)C++编译系统提供的系统函数是按类分别存放在不同的.h 文件(头文件)中的。
例如像平方根函数、 绝对值函数、 指数函数、 对数函数、 三角函数等常用数学函数放在 math.h 文件中(Visual C++放在 cmath.h 中);有关字符串处理的函数放在 string.h 中;判断字母、
数字、 大小写字母、 输入输出流的函数放在 iostream.h 中; 有关格式控制的函数放在 iomanip.h 中。另外,不同版本的编译系统或不同厂商提供的编译系统提供的系统函数可能不尽相同,
也可能放在不同的头文件中。因此,在使用系统函数之前,要阅读编译系统的使用手册,或 通过联机帮助系统了解某个系统函数是否提供?它被存放在哪个头文件中?调用前要将包 含被调用的系统函数所在的头文件用 include 语句包含进去。如果把头文件用错了,将导致 编译不成功。
(2)调用系统函数之前,要了解该函数的功能、参数类型、返回值类型等信息,便于正 确使用该函数。
4.7.1 常用数学函数 常用的数学函数包括:
(1)int abs(int num):求绝对值。
(2)double acos(double arg):求反余弦。
(3)double asin(double arg):求反正弦。
(4)double atan(double arg):求反正切。
(5)double cos(double arg):求余弦。
(6)double exp(double arg):求 e 的幂。
(7)double fabs(double arg):求浮点数的绝对值。
(8)long labs(long num):求长整型数的绝对值。
(9)double log(double num):自然对数。
(10)double log10(double num):以 10 为底的自然对数。
(11)double pow(double base, double exp):求幂。
(12)double sin(double arg):求正弦。
(13)double sqrt(double num):求平方根。
(14)double tan(double arg):求正切。
常用的数学函数在标准 C++文档中定义在 math.h 文件中, 而 Visual C++ 6.0 系统中定义在 cmath.h 文件中。
【例 4.20】 常用数学函数使用示例。
程序代码如下:
#include <iostream>
#include <cmath>
using namespace std;
void main() {
int a=3, b=4;
cout<<sqrt(a*a+b*b)<<endl;
cout<<pow(sqrt(a*a+b*b),2)<<endl;
cout<<exp(1)<<'\0'<<exp(1.5)<<endl;
}
程序的运行结果如下:
4.7.2 常用字符串处理函数
C++兼容标准 C 的字符串处理函数。本小节介绍其中几个比较常用的字符串处理函数。
C++字符串处理函数定义在 string.h 文件中。
以下给出的函数调用形式中的参数 str、str1 和 str2,除特别声明外,均是指字符串常量、
字符数组名或字符串存储空间开始地址(字符串指针) ,后两项内容将在后续章节介绍。
1.连接函数 strcat
函数原型:char *strcat(char *str1, const char *str2);
调用格式:strcat(str1,str2);
函数功能:将字符串 str2 连接到 strl 的后面,str2 的值不变。
2.字符串拷贝函数 strcpy 和 strncpy 函数原型:char *strcpy(char *str1,char *str2);
调用格式:strcpy(str1,str2);
函数功能:将字符串 str2 整个复制到字符数组 str1 中,str2 的值不变。
调用该函数时,一般 str1 是字符数组,且 str1 定义得足够大,以便能容纳被拷贝的 str2 的内容。例如:
strcpy(str1,"Changsha");
在某些应用中, 需要将一个字符串的前面一部分拷贝,其余部分不拷贝。 调用函数 strncpy 可实现这个要求。函数调用 strncpy(str1,str2,n)的作用是将 str2 中的前 n 个字符拷贝到 str1(附 加'\0') 。其中 n 是整型表达式,指明欲拷贝的字符个数。如果 str2 中的字符个数不多于 n,则 该函数调用等价于 strcpy(str1,str2)。
3.求字符串长度函数 strlen 函数原型:int strlen(char *str);
调用格式:strlen(str);
函数功能:求字符串的实际长度(不包括'\0'),由函数值返回。例如:strlen("good")函数 值为 4。
4.字符串比较函数 strcmp
函数原型:int strcmp(char *str1,char *str2);
调用格式:strcmp(str1,str2);
函数调用 strcmp(str1,str2)比较两个字符串大小。对两个字符串自左至右逐个字符相比较
(按字符的 ASCII 代码值的大小) , 直至出现不同的字符或遇到'\0'为止。 如果全部字符都相同,
则认为相等,函数返回 0 值;若出现不相同的字符,则以第一个不相同的字符比较结果为准。
若 str1 的某个不相同字符小于 str2 的相应字符, 函数返回一个负整数; 反之, 返回一个正整数。
注意,对字符串不允许进行相等“==”和不相等“!=”运算,必须用字符串比较函数对 字符串作比较。
5.字符串大写字母转换成小写字母函数 strlwr
函数调用 strlwr(str)将 str 中的大写字母转换成小写字母,要求 str 不能是字符串常量。
6.字符串小写字母转换成大写字母函数 strupr
函数调用 strupr(str)将 str 中的小写字母转换成大写字母。要求 str 不能是字符串常量。
7.子串查找函数 strstr
函数调用 strstr(str1,str2),在 str1 中查找是否包含子串 str2,若找到,则返回第一次出现 str2 的位置,否则,返回空指针 NULL。
8.int atoi(char *str) 将 str 字符串转换成整数。
9.long atol(char *str) 将 str 字符串转换成长整数。
10.double atof(char *str)
将 str 字符串转换成 double 型数值。
【例 4.21】 字符串处理函数使用示例。
程序代码如下:
#include <iostream>
#include <string>
using namespace std;
void main() {
char s[10]="First", s1[10]="";
cout<<strlen(s)<<endl;
cout<<strcat(s,"Name")<<endl;
cout<<strcpy(s1,"Changsha")<<endl;
cout<<strupr(s1)<<endl;
cout<<atof("123.789")<<endl;
}
程序的运行结果如下:
习题四
一、选择题
1.以下有关函数定义和调用的说法中,正确的是( )。
A.函数的定义就是指“函数”这个名词的概念
B.函数的声明就是提前写出函数定义的首部 C.一个函数只能调用除自己以外的函数 D.函数的返回值只能返回给它的直接调用者
2.以下有关函数参数的叙述不正确的是( )。
A.函数的形参命名可以任意,只要符合标识符规则 B.实参只能是常数
C.形参的值与实参的值不一定时刻保持一致 D.函数参数的值也可以是内存单元地址
3.以下有关变量的时间与空间属性的叙述不正确的是( )。
A.变量的时间属性是指变量有一定的生存期 B.变量的空间属性是指变量有一定的作用域
C.static 关键字加在变量定义语句前只能使变量的生存期延长 D.静态全局变量是指其作用域最多只局限于本文件范围
4.以下有关函数存储类别的叙述不正确的是( )。
A.内部函数又叫做静态函数,定义时用到 static 关键字 B.内部函数不能被定义它的文件外的语句调用 C.必须加 extern 关键字定义的函数才是外部函数
D.外部函数可以被定义它的文件之外语句调用,只是调用前需要用 extern 声明 二、填空题
1.函数的声明语句类似于函数定义中的 ;但它们之间有如下区别:函数的声明语句中,形参
名称可以 ,函数定义中的形参名称不可以 ;函数声明语句末尾 ,函数定义中的
部分的末尾 。
2.若有函数定义:float f(int x,char y){…}。将该函数声明为内联函数的语句为 。
3.全局变量定义在 位置,包括 和 两种。其中,后者的作用域不超出定义
它的文件范围,且后者的定义比前者的定义要多一个 关键字;而前者的作用域原则上可以扩展到程
序所有 中的所有 ,前提是只要在使用它的文件开头写形如 格式的声明语句。
4.static 加在局部变量定义前,改变局部变量的 但不改变它的 ;static 加在全局变量
定义前,改变全局变量的 但不改变它的 。static 加在函数定义首部时,是限制函数
的 ,使函数最多只能在 范围内可以被调用。
三、程序阅读题
程序 1:
#include <iostream.h>
long f1(int p) {
long f2(int);
long c=1,s;
int i;
for(i=1;i<=p;i++)
c=c*i;
int a=3,b=5; //a、b 为外部变量 max(int a,int b) //a、b 为外部变量 { int c;
四、程序设计题
1.对任意给定的两个正整数 m、n,用函数实现求 s=m!+n!。要求编写 2 个自定义函数,其一为求两数 之和,函数原型为:float add(int x, int y);其二为求某数阶乘,函数原型为:float fac(int n)。主函数中给出实 参,调用两者得到最终结果。
2.编写求[1,100]中所有素数之和的程序。其中,判断某个数 n 是否为素数用函数实现,函数原型可为:
int isprime(int n)。
3.试分别用非递归与递归函数方式编写求 a 的 n 次幂的函数,函数原型为:float pow(float a,int n),限 定 n≥0。
4. 试分别用非递归与递归函数方式编写求 s=1+2+…+n 的函数, 函数原型为: float sum(int n), 限定 n≥1。
5.编程实现对用户输入的英文字符进行输出,其中,判断输入字符为英文字符的功能用内联函数实现。
6.将一个求阶乘的函数 fac(函数原型同第 1 题)专门写在一个文件 file1.cpp 中,定义为外部函数;然
后在另一文件 file2.cpp 中计算 y=a!/b n ,其中,调用 fac 计算阶乘,调用本文件中的求幂运算函数 pow(函数
原型同第 3 题)。