《C++PrimerPlus》第八章 函数探幽

本文介绍了C++中的内联函数,用于减少函数调用的时间开销,以及引用变量的概念,作为函数参数使用时能直接操作原始数据。此外,还讨论了引用的特性,如必须初始化并始终绑定到同一对象,以及在结构体中的应用。最后,提到了默认参数、函数重载和函数模板,展示了C++的灵活性和泛型编程能力。
摘要由CSDN通过智能技术生成

这部分内容实际是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);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值