- 函数指针
- 内联函数
- 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关键字是为了解决什么问题出现的?
如下模板函数:
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++相关书籍,作为学习记录复习使用,方便日后查阅。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)