C++函数

C++函数,第1张

函数
  • 函数指针
  • 内联函数
  • decltype关键字
  • atuo关键字
  • 返回引用
  • const关键字
  • 二维数组

函数指针

概念:函数也是有地址的,而指向这个地址的指针就是函数指针
1、获取函数的地址
使用函数名即可,例如think()是一个函数,则think就是该函数的地址。


要将函数作为参数进行传递,必须使用函数名。


porcess(think);		//passes address of think() to porcess();	porcess可以在内部使用think
thought(think());	//passes return value of think() to thought(); thought函数调用首先调用think函数,返回值传递给thought

2、函数指针的声明
声明函数指针,须指定指针指向的函数类型,即指明函数的返回类型和参数列表
例:

double pm(int);
double (*pf)(int);//其函数指针形式

pam()替换为了(*pf)

double *pf(int); 这样就表示pf()是一个返回指针的函数
double (*pf)(int) pf是一个指向函数的指针

将函数的地址赋值给指针 pam()函数的特征标(参数列表)和返回类型必须与pf相同才可以
pf=pam;
3、使用指针来调用函数

double y=pf(5);	//两种形式都是可以的
double y=(*pf)(5);
内联函数

涉及关键字:inline
内联函数比普通函数运行稍微快一点,但是需要耗费更多的空间。



为什么运行要快一点?
函数在栈中进行调用,在main函数中,每次遇到一个函数,就需要跳转到该函数对应栈的位置进行使用。


而内联函数不需要,内联函数类似于直接把代码块添加进main函数中,不需要跳转的时间(个人看书理解)。


class A
{
public:
	void test()
	{
		cout<<"test"<<endl;//在类中声明并且定义的默认为内联函数,在类外定义需要加关键字inline
	}	
}

注:
即使我们加了inline关键字,最后它是否为内联函数也是编译器决定的,我们只是给它一个建议,如果函数块过大,即使声明为内联函数编译器也不会使得它成为内联函数。


decltype关键字

decltype关键字是为了解决什么问题出现的?
如下模板函数:

template<class T1, class T2>
void ft(T1 x, T2 y)
	{
		?type? xpy =x+y;
	}

变量xpy的类型我们应该如何确定?
如果T1为double T2为int,这种情况下两个变量和为double

为了解决这个问题decltype出现了
1、decltype关键字使用

int x;
decltype(x) y;//make y the same type as x

decltype(expression) var;
1、如果expression是一个没有用括号括起来的标识符,则war的类型与该标识符的类型相同
2、如果expression是一个函数调用,则var的类型与函数的返回类型相同
3、如果expression是一个左值,则var为指向其类型的引用。


要进入第三步,expression不能是未用括号括起来的标识符。



4、上述条件都不满足,则var的类型与expression的类型相同

上述得到xpy变量类型的方法如下:
decltype(x+y) xpy=x+y;
//验证1、
	double x = 5.5;
	double y = 7.9;
	double& rx = x;
	const double* p = &y;
	decltype(x) w;//w is type double
	decltype(rx) u = y;//u is double &
	decltype(p) v;//v is type const double * 这里并没有初始化
//验证2、
	decltype(indeed(3)) m;//m is type long 并不会实际调用函数 indeed为返回long类型的函数
	cout << typeid(m).name() << endl;//查看变量类型
//验证3、
	double xx = 4.4;
	decltype((xx)) r2 = xx;//r2 is double &
	decltype(xx) r1 = xx;//r1 is double
//验证4、
	int j = 3;
	int& k = j;
	int& n = j;
	decltype(j + 6) i1;//i1 type is int;
	decltype(100L) i2;//i2 type is long
	decltype(k + n) i3;//i3 type is int 表达式k+n不是引用,它是两个int的和

//decltype结合typedef使用
	typedef decltype(k + n) int_t;
	int_t x = 10;
atuo关键字

如下问题又该如何解决?

template<class T1, class T2>
	?type? ft(T1 x, T2 y)
	{
		return x+y;
	}

无法预先知道x和y的类型,而decltype(x+y)需要在声明参数后使用,如果返回类型设置为decltype(x+y),此时还未声明x,y。


如何确定函数返回的类型?
解决上述问题,出现了新增语法auto
例:
double h(int x,float y);---------->auto h(int x,float y)->double;
将返回类型移动到参数声明后面
将这个与decltype结合可以解决上述问题

template<class T1,class T2>
inline auto gt(T1 x, T2 y)->decltype(x + y)
{
	return x + y;
}
int main()
{
	int x = 10;
	double y = 1.1;
	decltype(gt(x, y)) m = gt(x, y);
	cout << "返回类型为:"<<typeid(m).name() << endl;//返回类型为double
}
返回引用

为什么要有返回引用?
当热是为了提高效率
传统的返回参数与传递函数参数(值传递)类似,计算关键字return后面的表达式,并将结果返回给调用函数,这个值会被复制到一个临时位置。


如果是我们自定义的数据类型,这个过程需要花费一些时间。


double m=sqrt(16.0);//值4.0将被复制到一个临时位置,然后被复制给m。


返回引用需要注意的问题

const free_throw & clone(free_throw &ft)
{
	free_throw newguy;   //first step to big error
	newguy=ft;			//copy info
	return newguy;		//return reference to copy
}

newguy是一个临时变量,当函数运行结束之后就被销毁了,而此处返回一个指向临时变量的引用。


这样是错误的
何时需要返回引用加const?
补充知识:
左值与右值:

  • 右值:常规(非引用)返回的类型,不能通过地址访问的值
  • 左值:左值的子表达式必须表示一块能够修改的内存块

因此既要返回引用,又不想被执行赋值 *** 作,则必须加const

const关键字
int age = 39;
const int* p = &age;//p指向const int
//*p = 20;//error p指针指向常量,常量自然无法更改
age = 20;
cout << *p << endl;//20

int* const p1 = &age;
int a = 10;
//p1 = &a;//error 常指针,无法修改指针的值,可以通过指针改变age的值
*p1 = a;
cout << age << endl;//10

后面表示声明的指针的名字,比如int* p表示p是指向int类型的指针。


那么int* const p,则这个const是修饰指针的,自然指针的地址就不能改变了。


二维数组

函数将二维数组作为参数

int sum(int (*ar2)[4],int size)    // 4是列数,行数传递给size
int sum(int arr[][4],int size)

注意:

int (*ar2)[4]//这个小括号不可以少 这样的意思是一个指向4个int组成的数组的指针
int *ar2[4] //四个指向int的指针构成的数组
arr				//pointer to first row of an array of 4 int
arr+r			//pointer to row r(an array of 4 int)
*(arr+r)		//row r
* (arr+r)+c		//pointer int number c in row r
* (*(arr+r)+c)	//vlaue of int number c in row r

本文内容来自于C++相关书籍,作为学习记录复习使用,方便日后查阅。


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/578258.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-11
下一篇 2022-04-11

发表评论

登录后才能评论

评论列表(0条)

保存