c++学习7、函数探幽

#include<iostream>
#include<string>
using namespace std;
struct crdit
{
	string name;
	int age;
	string address;
};
struct job
{
	char name[40];
	double salary;
	int floor;
};
inline  double square(double x) { return x * x; }//定义了一个内联函数square——多行的内联函数会报告!
#define squarex(x) x*x//能用定义式宏的地方尽量用内联函数!!根更好
void swap(int& a, int& b);//将引用变量作形参
double refcube(double& ra);
int sum(const int& a, const int& b);
void set_crdit(crdit& fp);
crdit& dis(crdit& pf);//返回结构引用的函数比直接返回结构其效率跟更高
char* left(const char* str, int n = 1);//这里将n的默认值设置为1,在没有对应的n参数时,自动生成n=1这个参数
void print(const char* str, int length);//#1
void print(double a, int b);//#2
void print(long x);//#3               #1、2、3都是重载函数————可以发现特征值都不同
void cube(double x);//#4
void cube(double& x);//#5错误使用      #4、5在进行函数重载时,编译器会把类型引用和类型本身视为同一个特征值

template <typename T>
void Swap(T& a, T& b);//#6,定义了函数模板Swap

template <typename T>//       #6,7是一对重载的模板,也是根据参数(特征值)进行匹配
void Swap(int* a, int* b, int n);//#7,

template <>void Swap<job>(job& j1, job & j2);//显示具体化——当编译器找到与函数调用匹配的定义时,直接引用
int main()
{
	//内联函数与常规函数不同的调用方式:常规函数是利用指令地址进行跳转,而内联函数将相应函数代码替代函数调用
	//但这种代价是会消耗更多的内存————生成多个副本
	//执行时间过长则用常规调用————过短则用内联函数
	//采取的措施为在函数声明和定义时加上关键字inline————通常是直接将整个定义放在提供原型的地方
	using namespace std;
	double a = square(7.5 + 23.5);//内联函数可以直接传递表达式————这与函数式宏定义不同
	cout << a;
	//c++新增一复合类型————引用变量&、
	//引用变量是已定义变量的别名——不是拷贝——是可以修改原始值————与指针有点相似
	int rats;
	int& rodents = rats;//创建引用变量rodents,&不是地址运算符,而是类型标识符的一部分
	//其中rodents和rats指向同一个值和内存单元inline  
	rats = 5;
	cout << rats << " " << rodents;
	rodents = 8;//修改了rodent,也就修改了rats的值
	cout << rodents << " " << rats;
	//引用变量和指针最大的区别是引用变量一定要在声明时进行初始化
	//即只能通过初始化声明来设置引用,不能通过赋值来设置
	int c, b;
	cin >> c >> b;
	swap(c, b);
	cout << c << " " << b;
	//引用的属性和特长之处
	//如果在引用的请况上又不想修改原始数据,可加上const,修改时会报错!!!
	//如果执行refcube(x+3.0)!这时会生成一个临时变量,再将引用变量指向它
	//在2种情况下会生成临时变量:1、实参类型正确,但不是左值 2、实参类型不正确,当可以转化为正确类型P215页
	//种种迹象表明尽可能使用const!!!!
	cout << sum(a, b);

	//将引用用于结构————与变量的使用差不多
	crdit temp;
	cin >> temp.address >> temp.age >> temp.name;
	set_crdit(temp);//将结构用于引用
	
	//将引用用于类对象--一般类对象都是用引用作函数的形参————对于
	//书本P224页

	//c++的另一个功能————默认参数--必须在函数原型时设计
	char aise[50];
	cin.getline(aise, 50);//这里的50可以不用传递参数,有默认值了
	char* p = left(aise, 50);

	//函数重载(函数多态)————让你能使用多个同名函数—————关键在于函数的参数列表,也叫函数特征值
	//函数重载的前提是特征值不同————c++会根据参数自动选择对应的函数!
	double c;
	int d;
	long e;
	cin >> d >> e >> c;
	print(c, d);//使用的是print#2
	print(e);//使用的是print#3
	//当重载和引用相结合时————编译器将调用最匹配的版本!
	/*void sink(double &rs)
	  void sink(const double &r2)
	  void sink(double &&r3)            */
	//根据参数是左值、const还是右值来指定函数行为!!!
	//重载函数看情况使用

	//引入函数模板————通用函数,使用泛型来定义函数————又称通用编程
	//注意函数模板并不能缩短可执行程序
	int n, m;
	double h, g;
	cin >> n >> m >> h >> g;
	Swap(n, m);//传递整型,模板将生成相应的整型函数,下同
	Swap(h, g);
	//模板的局限性:针对结构或数组这类数据结构可能无法处理某些类型————引入显示具体化
	//1、显示具体化的原型应为templast<>打头 2、具体化优先于常规模板,常规函数优于具体化和常规模板
	//实列化————编译器通过函数模板方案创建了一个函数实列————隐式实列化————也有显示实列化:
	//templast void swap<int>(int ,int )   ————于显示具体化不同点在于templast后面没加<>



	//有关重载解析的内容,在书P237页处
	//编译器如果无法完成重载解析,将会抛出二义性的错误信息

	//c++11中新增关键字decltype()
	//在函数中不知道要用什么类型承接表达式或变量时候,可以使用decltype()
	//列:decltype(x+y) xpy = x+y;  __不知道x和y的类型时,可以这样做

	//c++后置返回类型————当不知道函数返回类型时
	//auto gt (T& x,T& y) -> decltype(x+y)
	//->decltype()被称为后置返回类型,auto是一个占位字符,表示返回类型提供的类型


}
void swap(int& a, int& b)//使用引用变量作形参,可以像指针一样对其原始数据操作
{//并不是按值传递的拷贝
	int temp = b;
	b = a;
	a = temp;
}
double refcube(double& ra)
{
	ra *= ra * ra;
	return ra;
}
int sum(const int& a, const int& b)
{

}
void set_temp(crdit& fp)
{
	cout << fp.address << fp.age << fp.name;
	cout << "plase try to write:";
	cin >> fp.address >> fp.age;//这里其实是对原始数据结构进行修改!!!
}
crdit& dis(crdit& pf)
{
	pf.age++;
	return pf;//直接返回引用,不用复制到一个临时的位置,可以直接赋值到结构上
}
char* left(const char* str, int n = 1)//这里的默认值可写可不写,在函数原型时已经定义了
{
	if (n < 1)
		n = 0;
	char* p = new char[n + 1];
	int i = 0;
	for (int i; i < n && str[i]; i++)
		p[i] = str[i];
	while (i <= n)
		p[i++] = '\0';
	return p;
}
void print(double a, int b)
{
	cout << a / b;
}
void print(long x)
{
	cout << x;
}
template <typename T>//注意关键字template和typename不能省略,T为泛型
void Swap(T& a, T& b)//传递不同类型的参数,会生成不同类型的函数
{
	T temp;
	temp = b;
	b = a;
	a = temp;
}
template <>void Swap<job>(job& j1, job& j2)
{
	double temp;
	temp = j1.salary;
	j1.salary = j2.salary;
	j2.salary = temp;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值