这部分内容实际是C++的新增特性,初级信息学不要求会(考纲没有这项)
8.1 C++内联函数
内联函数与常规函数的区别不在于编写方式,而在于C++编译器如何将它们组合到程序中。
内联函数的开销主要是内存的存储空间,相当于用空间代替了时间,它会快一些但要占用空间。
#include <iostream>
using namespace std;
inline double square(double x){return x*x;}
int main()
{
double a,b;
double c = 13.0;
a = square(5.0);
b = square(4.5 + 7.5);
cout<<"a = "<<a <<" , b = "<<b<<"\n";
cout<<"c = "<<c;
cout<<", c square = "<< square(c++)<<"\n";
cout<<" Now c = "<<c<<"\n";
return 0;
}
输出:
a = 25 , b = 144
c = 13, c square = 169
Now c = 14
8.2 引用变量
引用变量的主要用途是用作函数的形参。通过将引用变量用作参数,函数将使用原始数据,而不是其副本。这样除指针之外,引用也为函数处理大型结构提供了一种非常方便的途径,同时对于设计类来说,引用也是必不可少的。
8.2.1 创建引用变量
要将rodents作为rats变量的别名,可以这样做:
int rats;
int & rodents = rats;
其中,&不是地址运算符,而是类型标识符的一部分。就像声明中的char*指的是指向char的指针一样,int &指的是指向int的引用。上面的引用声明允许rats和rodents互换——它们指向相同的值和内存单元。
#include<iostream>
using namespace std;
int main()
{
int rats=101;
int & rodents = rats;
cout<<"rats = "<<rats <<" ,rodents = "<<rodents<<endl;
cout<<"rats address = "<<&rats <<", rodents address = "<<&rodents<<endl;
rodents++;
cout<<"rats = "<<rats <<" ,rodents = "<<rodents<<endl;
cout<<"rats address = "<<&rats <<", rodents address = "<<&rodents<<endl;
return 0;
}
[输出]:
rats = 101 ,rodents = 101
rats address = 0x73ff08, rodents address = 0x73ff08
rats = 102 ,rodents = 102
rats address = 0x73ff08, rodents address = 0x73ff08
** 特别注意的是地址在rodents自增前后并没有变化,我估计这就是引用和指针的差别处
准确地说,rodents++操作将一个有两个名称的变量加1。
另外注意:必须在声明引用变量时进行初始化。
引用更接近const指针,必须在创建时进行初始化,一旦与某个变量关联起来,就将一直效忠于它。也就是说:
int & rodents = rats;
实际上是下述代码的伪装表示:
int * const pr = &rats;
8.2.2 将引用用作函数参数
引用经常被用作函数参数,使得函数中的变量名成为调用程序中的变量的别名。这种传递参数的方法称为按引用传递。按引用传递允许被调用的函数能够访问调用函数中的变量。
#include<iostream>
using namespace std;
void swapr(int & a,int & b);
void swapp(int* a,int* b);
void swapv(int a,int b);
int main()
{
int value1,value2;
value1 = 300 , value2 = 350;
cout<<value1<<" "<<value2<<endl;
swapr(value1,value2);
cout<<value1<<" "<<value2<<endl;
swapp(&value1,&value2);
cout<<value1<<" "<<value2<<endl;
swapv(value1,value2);
cout<<value1<<" "<<value2<<endl;
return 0;
}
void swapr(int & a,int & b)
{
int temp;
temp = a ;
a = b;
b = temp;
}
void swapp(int* a,int* b)
{
int temp = *a;
*a = *b;
*b = temp;
}
void swapv(int a,int b)
{
int temp = a;
a = b;
b = temp;
}
【输出】
300 350
350 300
300 350
300 350
小结:按引用或按指针都能成功改变值,按值方式就不能交换成功。按引用和指针的区别就是指针方式,时必须解引用。
8.2.3 引用的属性和特别之处
在函数中,如果参数是引用类型的参数,则原值也会变化。通常使用的引用参数可以改为常量类型。
8.2.4 将引用用于结构
如下结构定义:
struct free_throws{
std::string name;
int made;
int attempts;
float percent;
}
则可以编写函数原型:
void set_pc(free_throws & ft);
如果不希望函数修改传入的结构,可以使用 const:
void set_pc(const free_throws & ft);
默认参数
#include<iostream>
const int Arsize=80;
char * left(const char* str,int n);
int main()
{
using namespace std;
char sample[Arsize];
cout<<"Enter a string:\n";
cin.get(sample,Arsize);
char* ps = left(sample,4);
cout<<ps<<endl;
delete [] ps;
ps = left(sample,1);
cout<<ps<<endl;
delete [] ps;
return 0;
}
char* left(const char* str,int n){
if(n<0) n=0;
char* p = new char[n+1];
int i;
for(i=0;i<n && str[i];i++) //等价于for(i=0;i<n && str[i]!='\0';i++)
p[i]=str[i];
while(i<=n) p[i++]='\0';
return p;
}
小结:如果没有处理边界,情况变得很不理想
函数重载
重载指的是可以有多个同名的函数,因此对名称进行了重载。
函数模板
模板化编程是c++编译器提供的功能。函数模板允许以任意类型的方式来定义函数,例如:
template <typename AnyType>
void swap(AnyType &a,AnyType &b)
{
AnyType temp;
temp =a;
a=b;
b=temp;
}
调用函数时:
int i=20,j=30;
swap(i,j);
double i=24.1,j=29.4;
swap(i,j);