C++函数(详细版)

2023-11-14

函数指针

概念:函数也是有地址的,而指向这个地址的指针就是函数指针
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++相关书籍,作为学习记录复习使用,方便日后查阅。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++函数(详细版) 的相关文章

随机推荐

  • 【随笔】在vue项目使用icon

    Vue引用icon图标 利用i标签 快速添加页面图标 利用i标签 快速添加页面图标 之前写项目遇见图标都是下载成icon然后用img展示 但是图标写多了就会变得特变麻烦 光下载的图标就会占很大空间 所以学着用i写 首先进入项目 在项目下建一
  • python model函数_python--model进阶

    一 QuerySet 1 可切片 使用Python 的切片语法来限制查询集记录的数目 它等同于SQL 的LIMIT 和OFFSET 子句 gt gt gt Entry objects all 5 LIMIT 5 gt gt gt Entry
  • 【动态规划】LCS算法:求两字符串最大公共子序列/删除字符使成为回文串

    问题描述 给定一个字符串s 你可以从中删除一些字符 使得剩下的串是一个回文串 如何删除才能使得回文串最长呢 输出需要删除的字符个数 例如 输入 google 输出 2 思路 回文串通常可以用逆序的方式寻找思路 例如字符串google逆序后e
  • 运维小知识之CDN内容分发网络原理解析

    0x00 前言简述 基础概念 工作原理 组成部分 应用场景 0x01 基础配置 CDN 入门配置 CDN 跨域设置 CDN 响应头参数 扩充 0x02 边缘脚本与程序 EdgeScript 边缘脚本 EdgeRoutine 边缘程序 0x0
  • 【linux】宝塔面板安装命令

    一 查看是否安装 宝塔面板 bt 14 已安装会列出宝塔登录地址 否则 bash bt command not found 下载及安装命令 yum install y wget wget O install sh http download
  • 移动DICT项目是什么?

    DICT项目 我们运营商的伙伴 很多人都知道我们的DICT 但是大家知不知道什么是DICT 你想一想 所谓的DICT 就是指的大数据技术与IT和CT的深度融合 实际上 DICT的可以拆分成三个词 第一个DT 云和大数据的技术 第二个IT 信
  • LeetCode--初级算法--反转链表

    参考 反转链表的方法 反转一个单链表 示例 输入 1 gt 2 gt 3 gt 4 gt 5 gt NULL 输出 5 gt 4 gt 3 gt 2 gt 1 gt NULL 进阶 你可以迭代或递归地反转链表 你能否用两种方法解决这道题 分
  • pandas学习笔记--取表格中特定行或列或特定位置元素

    先生成一个演示dataframe df pd DataFrame np random randn 5 5 columns A B C D E index a b c d e df 取前两行 df 0 2 取后两行 df 2 取倒数第二行 d
  • 什么是DAO,DAO是什么?DAO全面解析

    什么是DAO DAO是什么 DAO是Decentralized Autonomous Organizationd简写 即去中心化自治组织 有时也被称为分布式自治公司 DAC 有共同的目标或是共识 有明确的核心价值观 它的民主化的投票机制 决
  • idea Maven异常:Could not find artifact(本地仓库确实存在)

    首先检查自己的maven环境有无问题 1 首先尝试清楚idea中的缓存如下图所示 当pom没有爆红时 按照上图操作还是无效 可以尝试重新新建一下自己的repository把自己原来的仓库重命名备份下以防万一 我的是这样操作解决了问题 希望能
  • 实战攻防演习之红队

    0x00 什么是红队 红队 一般是指网络实战攻防演习中的攻击一方 红队一般会针对目标系统 人员 软件 硬件和设备同时执行的多角度 混合 对抗性的模拟攻击 通过实现系统提权 控制业务 获取数据等目标 来发现系统 技术 人员和基础架构中存在的网
  • 【JavaEE】多线程案例-单例模式

    文章目录 1 前言 2 什么是单例模式 3 如何实现单例模式 3 1 饿汉模式 3 2 懒汉模式 4 解决单例模式中遇到的线程安全问题 4 1 加锁 4 2 加上一个判断解决频繁加锁问题 4 2 解决因指令重排序造成的线程不安全问题 1 前
  • 应用场域的深度融合与创新构想

    近年来 随着人工智能技术的迅速发展 自然语言处理技术也取得了显著的进步 其中 ChatGPT作为一种高效的自然语言处理模型 已经在许多领域得到了广泛的应用 本文主要围绕ChatGPT的调研分析以及其与应用场域的结合构想展开讨论 一 Chat
  • BigDecimal转String字符串的代码

    BigDecimal转String字符串的代码 Posted on 2016 06 28 11 17 上善其若水 厚德载物 阅读 8896 评论 0 编辑 收藏 举报 bigdeciaml stripTrailingZeros toPlai
  • 求最大子序列和的四种方法

    求一个给定序列的连续子序列中和最大的那个子序列的和 下边方法只求和 没有找出最大子序列 用到的头文件和宏定义如下 include stdafx h include
  • 机器学习:聚类算法实现流程

    学习目标 掌握K means聚类的实现步骤 k means其实包含两层内容 K 初始中心点个数 计划聚类数 means 求中心点到其他数据点距离的平均值 1 k means聚类步骤 1 随机设置K个特征空间内的点作为初始的聚类中心 2 对于
  • 抖音矩阵系统功能开发及开发文档说明

    抖音账号矩阵系统开发文档是矩阵系统开发的重要文件 涵盖了矩阵系统的设计 实现 测试和维护等方面的相关信息 这些信息是矩阵系统开发人员进行系统开发的重要参考 有助于确保系统开发的顺利进行和最终的实现效果 矩阵系统开发文档一般包括以下几个方面的
  • mysql的悲观锁和乐观锁

    悲观锁 悲观锁指的是对数据被外界 包括本系统当前的其他事务 以及来自外部系统的事务处理 修改持保守态度 因此 在整个数据处理过程中 将数据处于锁定状态 悲观锁的实现 往往依靠数据库提供的锁机制 也只有数据库层提供的锁机制才能真正保证数据访问
  • MyBatis框架的作用?

    1 MyBatis 是一个优秀的基于 java 的持久层框架 它内部封装了 jdbc 使开发者只需要关注 sql 语句本身 而不需要花费精力去处理加载驱动 创建连接 创建 statement 等繁杂的过程 2 MyBatis为了和数据库进行
  • C++函数(详细版)

    函数 函数指针 内联函数 decltype关键字 atuo关键字 返回引用 const关键字 二维数组 函数指针 概念 函数也是有地址的 而指向这个地址的指针就是函数指针 1 获取函数的地址 使用函数名即可 例如think 是一个函数 则t