2021.03.03
看书学习记录一些区别于C的部分
一、函数与预处理
1、函数重载
当遇到函数的功能相似,但函数和参数的类型可能不同的情况下,为了避免重复的命名。在C++中允许用同一个函数名定义多个函数,这些函数的参数个数和参数类型不同,这就叫做函数重载。
例如:分别求三个整型、双精度和长整型数的最大值;可以如下定义:
#include <iostream>
using namespace std;
int main()
{
int max(int a,int b,int c);
double max(double a,double b,double c);
long max(long a,long b,long c);
int i1,i2,i3,i;
cin >>i1 >>i2 >>i3;
i = max(i1,i2,i3);
cout << "i_max=" <<i <<endl;
double d1,d2,d3,d;
cin >>d1 >>d2 >>d3;
d = max(d1,d2,d3);
cout << "d_max=" <<d <<endl;
long g1,g2,g3,g;
cin >>g1 >>g2 >>g3;
g = max(g1,g2,g3);
cout << "g_max=" <<g <<endl;
}
int max(int a,int b,int c)
{
if(b >a) a=b;
if(c >a) a=c;
return a;
}
double max(double a,double b,double c)
{
if(b >a) a=b;
if(c >a) a=c;
return a;
}
long max(long a,long b,long c)
{
if(b >a) a=b;
if(c >a) a=c;
return a;
}
运行结果如上图所示,重载的函数体并不要求相同;
参数的个数和类型可以都不同。但不能只有函数的类型不同而参数的个数和类型相同,如下就是错误的使用:
int f(int);
double f(int);
void f(int);
2、函数模板
对于上面的问题,当函数体相同,只有参数的类型不同,这时候可以使用XC++提供的函数模板,用一个虚拟的类型来代替。
例子如下:
使用方法为:
template 或template
当然,参数的类型个数还可以是多个,如
template <class T1,typename T2>
#include <iostream>
using namespace std;
template <typename T>
T max(T a,T b,T c)
{
if(b >a) a=b;
if(c >a) a=c;
return a;
}
int main()
{
int i1= 185,i2=-76,i3=567,i;
double d1=56.78,d2=90.23,d3=-312.45,d;
long g1=67854,g2=-912456,g3=673456,g;
i = max(i1,i2,i3);
g = max(g1,g2,g3);
d = max(d1,d2,d3);
cout << "i_max=" <<i <<endl;
cout << "d_max=" <<d <<endl;
cout << "g_max=" <<g <<endl;
return 0;
}
运行的结果和上面函数重载的结果一致。
3、递归函数
在调用一个函数的过程中又出现直接或者间接的调用该函数本身,称为函数的递归调用,C++允许函数的递归调用。包含递归调用的函数称为递归函数。
例:用递归方法求n!
#include <iostream>
using namespace std;
long fcn(int n); //声明函数
int main()
{
int n;
long y;
cout <<"please input an integer:";
cin >>n;
y=fcn(n);
cout <<n <<"!="<<y <<endl;
return 0;
}
long fcn(int n)
{
long f;
if(n<0)
{
cout <<"n<0,error!"<<endl;
f= -1;
}
else if(n==0 ||n==1) f=1;
else f=n*fcn(n-1);
return f;
}
4、寄存器变量
为了提高效率,节约时间,C++允许将一些使用频繁的局部变量放在寄存器中,这种变量叫做寄存器变量。关键词为register
如:register int x;
二、指针
1、引用
C++增加了“引用“机制来弥补指针由于太灵活,赋值不规范而引起的复杂错误。
引用的作用是为变量起一个别名。
如
int a;
int &b=a; //声明b是a的引用
以上语句声明了b是a的引用,即b是a的别名,这样声明之后,a或者b的作用相同,代表同一个变量。&是引用声明符,并不代表地址。
C++把引用型作为函数形参,弥补了C语言中只有值传递方式即“值形参“。
例:对3个变量按由小到大的顺序排序。
#include <iostream>
using namespace std;
long fcn(int n); //声明函数
int main()
{
void sort(int &,int &,int &); //函数声明,形参是引用类型
int a,b,c; //a,b,c是需要排序的变量
int a1,b1,c1; //a1.b1.c1是最终排好的数列
cout <<"please enter 3 integers:";
cin >>a >>b >>c; //输入a,b,c
a1 = a;b1 = b;c1 = c;
sort(a1,b1,c1);
cout << "sorted order is"<<a1 <<" "<<b1 <<" "<<c1 <<endl;
return 0;
}
void sort(int &i,int &j,int &k) //对i,j,k3个数排序
{
void change(int &,int &); //函数声明,形参是引用类型
if(i >j) change(i,j); //使i小于j
if(i >k) change(i,k); //使i小于k
if(j >k) change(j,k); //使j小于k
}
void change(int &x,int &y)
{
int temp;
temp = x;
x = y;
y = temp;
}
三、自定义数据类型
1、动态分配和撤销内存的运算符new和delete
在软件开发过程中,常常需要动态地分配和撤销内存空间,例如对动态链表中结点的插入和删除。
在C中利用库函数malloc和free来分配和撤销内存空间
C++中提供了较简单而功能较强的运算符new和delete来取代malloc和free。
new运算符使用的一般格式为:
new 类型 [初值]
new int(100); //开辟了存放整数的空间,并指定该整数的初值为100,返回一个指向该存储空间的地址
new char[10]; //开辟一个存放字符数组(10个元素)的空间,返回首元素的地址
new int [5][4]; //开辟一个存放二维数组(大小为5*4)的空间,返回首元素的地址(数组空间不能指定初值在用new分配空间时)
float *p=new float(3.112); //开辟一个存放单精度数的空间,并指定该实数的初值为
//3.112,将返回的该空间的地址赋值给指针变量p
delete运算符使用的一般格式为:
delete [] 指针变量
撤销上面的指针例子为:delete p;
delete [ ] pt; // 在指针变量前面加一对方括号,表示是对数组空间的操作。
例子:开辟空间以存放一个结构体变量
#include <iostream>
#include <string>
using namespace std;
struct Student //声明结构体类型Student
{
string name;
int num;
char sex;
};
int main()
{
Student *p; //定义指向结构体类型Student的数据的指针变量
p = new Student; //用new运算符开辟了一个存放Student型数据的空间
p->name = "Wang Ming"; //向结构体变量赋值
p->num = 123;
p->sex = 'm';
cout <<p->name<<endl<<p->num<<endl <<p->sex <<endl; //输出各成员
delete p; //撤销该空间
return 0;
}
上面的程序并没有定义结构体变量,而是定义了一个基类型为Student的指针变量p,用new开辟一段空间以存放一个Student类型的变量。