复习C++的核心知识

函数与参数

传值参数、模板函数、引用参数、常量引用参数

传值参数

int abc(int a,int b,int c) {
return a + b * c;
}

a、b、c是函数abc的形参,下面语句中调用函数abc:

z = abc(2,x,y);

2、x、y就是分别于a b c对应的实参,形参a、b、c实际上是传值参数,在运行时,函数abc执行前,将实参复制给形参,复制过由形参类型的复制构造函数来完成,如果类型不同会进行转换。当函数运行结束后,形参类型的析构函数负责释放形式参数

模板函数

将上述abc函数改写的更具有通用性,参数类型是一个变量,其值由编译器决定,即使用模板语句

template<class T>
T abc(T a,T b,T c) {
return a + b * c;
}

引用参数

使用形参会增加程序运行的时间,上述函数中,当a、b、c是传值参数时,一进入函数调用,类型T的复制构造函数就会启用,返回时,析构函数就会启用,如果T是比较复杂的类型,复制构造函数和析构函数可能带来较大的开销。使用引用参数,便不会调用复制构造函数和析构函数

template<class T>
T abc(T &a,T &b,T &c) {
return a + b * c;
}

常量引用参数

常量引用下指明的引用参数不能被函数修改

template<class T>
T abc(const T &a,const T &b,const T &c) {
return a + b * c;
}

使用const来指明函数不可修改的引用参数

综上可以得到更通用的写法:

template<class Ta,class Tb,class Tc>
Ta abc(const Ta &a,const Tb &b,const Tc &c) {
return a + b * c;
}

返回值

一个函数可以返回一个值、一个引用或一个常量引用,在上述例子中,返回的对象被复制到调用环境中,函数所计算出来的表达式结果被存储在一个局部的临时变量中,当函数结束时,当函数结束时,这个临时变量所占用的空间将被释放,为了不丢失这个值,在释放空间之前,要把这个值从临时变量复制到调用该函数的环境中去。但如果给函数返回类型增加一个后缀&,便指定了一个引用返回:

T& mystery(int i,T &z)

使用语句return z返回,这种形式不会将z的值复制到返回环境中,当函数结束时,形参i以及所有的局部变量的空间都被释放掉,z是对一个实参的引用,所以不受影响

重载函数

一个函数的签名,是由这个函数的形参类型及其个数确定的。定义多个同名函数的机制叫函数重载,将函数调用语句中的签名与函数定义中的签名进行匹配,编译器就可以确定哪一个重载函数被调用

float abc(float a,float b,float c) {
return a * b + c;
} int abc(int a,int b,int c) {
return a * b + c;
}

异常

异常是表示程序出现错误的信息

抛出异常

可以对一些异常情况进行检查,当查出一个异常就抛出,例如下方程序,当三个参数都大于0时才计算表达式的值,其他情况都抛出异常

int abc(int a,int b,int c) {
if (a <= 0 || b <= 0 || c <= 0) {
throw "All parameters should be > 0";
}
return a + b * c;
}

程序可能抛出的异常有很多类型,C++具有一个异常类的层次结构,类exception是根,标准C++函数通过抛出一种异常来表明异常的出现,而这种异常是从基类exception派生的类型

处理异常

一段代码抛出的异常由包含这段代码的try语句块来处理

int abc(int a,int b,int c) {
if (a <= 0 || b <= 0 || c <= 0) {
throw "All parameters should be > 0";
}
return a + b * c;
} int main(void) {
try {
cout << abc(2,0,4) << endl;
} catch (char const* e) {
cout << "The parameters to abc were 2,0 and 4" << endl;
cout << "An exception has been thrown" << endl;
cout << e << endl;
} return 0;
}

紧跟在try块之后的catch块,每一个catch块都有一个参数,参数的类型决定了这个catch块要捕获的异常类

输出:

The parameters to abc were 2,0 and 4
An exception has been thrown
All parameters should be > 0

可以有多个catch块,如果有一个异常被抛出,那么try块的正常运行停止,程序进入第一个能捕获到这种异常类型的catch块,其他catch块将被忽略,如果没有一个catch块能够与抛出的异常类型相对应,那么异常就会跨越嵌入在try块里的层次结构,寻找在层次结构中能够处理这个异常的第一个catch块,如果依然没有,那么程序非正常停止

动态存储空间分配

操作符new

new用于进行动态存储分配或运行时存储分配,其值是一个指针,指向所分配空间,例如给一个整数动态分配存储空间,并复制为10:

int *y = new int(10);

等价于:

int *y = new int;
*y = 10;

操作符new分配了一块能够存储一个整数的空间,并将该空间的指针赋给y,y是对整数指针的引用,而*y是对整数本身的引用

一维数组

动态存储分配的方式创建一维数组,如下创建一个长度为n的一维浮点数组

float *x = new float[n];

操作符new为n个浮点数分配了存储空间,并返回第一个浮点数空间的指针

异常处理

如果计算机没有足够的内存可以分配,那么new就会抛出一个bad_alloc类型的异常,可以利用try-catch来捕获:

int main(void) {
int n = 10;
float *x;
try {
x = new float[n];
} catch (bad_alloc e) {
cerr << "Out of Memory" << endl;
::exit(1);
} return 0;
}

二维数组

使用动态分配创建一个二维数组

template <class T>
void make2dArray(T** &x,int numberOfRows,int numberOfColumns) {
x = new T*[numberOfColumns];
for (int i=0;i<numberOfRows;i++) {
x[i] = new int [numberOfColumns];
}
}

如果数组的列数在编译时是未知的,那么不可能仅调用一次new就能创建这个二维数组,要构造这样的二维数组,可以将其看作是油若干行所构成的结构,每一行用new来创建一个一维数组

释放内存空间:

template<class T>
void delete2dArray(T** &x,int numberOfRows) {
for (int i=0;i<numberOfRows;i++) {
delete[] x[i];
}
delete[] x;
x = NULL;
}

分两步释放二维数组空间,首先释放为每一行所分配的空间,然后释放为行指针所分配的空间,将x置NULL,防止用户继续访问已被释放的空间

C++核心知识回顾(函数&参数、异常、动态分配)的更多相关文章

  1. Docker 核心知识回顾

    Docker 核心知识回顾 最近公司为了提高项目治理能力.提升开发效率,将之前的CICD项目扩展成devops进行项目管理.开发人员需要对自己的负责的项目进行流水线的部署,包括写Dockerfile ...

  2. [C#] C# 知识回顾 - 学会处理异常

    学会处理异常 你可以使用 try 块来对你觉得可能会出现异常的代码进行分区. 其中,与之关联的 catch 块可用于处理任何异常情况. 一个包含代码的 finally 块,无论 try 块中是否在运行 ...

  3. [C#] C# 知识回顾 - 学会使用异常

    学会使用异常 在 C# 中,程序中在运行时出现的错误,会不断在程序中进行传播,这种机制称为“异常”. 异常通常由错误的代码引发,并由能够更正错误的代码进行 catch. 异常可由 .NET 的 CLR ...

  4. Java核心知识体系3:异常机制详解

    1 什么是异常 异常是指程序在运行过程中发生的,由于外部问题导致的运行异常事件,如:文件找不到.网络连接失败.空指针.非法参数等. 异常是一个事件,它发生在程序运行期间,且中断程序的运行. Java ...

  5. Python 编程核心知识体系-函数(二)

    函数

  6. python---基础知识回顾(二)(闭包函数和装饰器)

    一.闭包函数: 闭包函数: 1.在一个外函数中定义了一个内函数 2.内函数里运用了外函数的临时变量,而不是全局变量 3.并且外函数的返回值是内函数的引用.(函数名,内存块地址,函数名指针..) 正确形 ...

  7. c++11-17 模板核心知识(十二)—— 模板的模板参数 Template Template Parameters

    概念 举例 模板的模板参数的参数匹配 Template Template Argument Matching 解决办法一 解决办法二 概念 一个模板的参数是模板类型. 举例 在c++11-17 模板核 ...

  8. [C#] C# 知识回顾 - 你真的懂异常(Exception)吗?

    你真的懂异常(Exception)吗? 目录 异常介绍 异常的特点 怎样使用异常 处理异常的 try-catch-finally 捕获异常的 Catch 块 释放资源的 Finally 块 一.异常介 ...

  9. [C#] C# 知识回顾 - 异常介绍

    异常介绍 我们平时在写程序时,无意中(或技术不够),而导致程序运行时出现意外(或异常),对于这个问题, C# 有专门的异常处理程序. 异常处理所涉及到的关键字有 try.catch 和 finally ...

  10. $Django 路飞之小知识回顾,Vue之样式element-ui,Vue绑定图片--mounted页面挂载--路由携带参数

    一 小知识回顾 1 级联删除问题 2 一张表关联多个表,比如有manytomanyfileds forignkey,基于对象查询存在的问题:反向查询的时候  表名小写_set.all()不知是哪个字段 ...

随机推荐

  1. hdu:最大点权(强连通分量kosaraju)

    Problem Description给定一个有向图,每个点ii有点权a_ia​i​​,请对于每个点ii,找到ii能到达的点中点权的最大值(包括ii点). Input第一行包含一个正整数T(1\leq ...

  2. MySQL Workbench常用快捷键及修改方法

    常用快捷键: 1. 执行整篇sql脚本:Ctrl + Shift + Enter 2. 执行当前行:Ctrl + Enter 3. 注释/取消注释: Ctrl + / 4. 格式化sql语句(美化sq ...

  3. ROS突发限速参考资料

    MT-Rate-Limit - Datarate limitation for clients. Format is: rx-rate[/tx-rate] [rx-burst-rate[/tx-bur ...

  4. nhrhrhr

    每名学生按规定时间进行答辩,答辩总时间控制在12分钟,其中包括学生报告7分钟.提问以及回答问题5分钟. 1.答辩开始前由答辩委员会组长宣布答辩程序:学生的答辩顺序由教师确定,前一名学生答辩时,下一名答 ...

  5. Word 给公式添加题注解决交叉引用中包含公式

    简记:回车,然后 Ctrl +Alt+Enter https://blog.csdn.net/wsj_jerry521/article/details/115163456

  6. vue3 vue-i18n 入口文件配置报警

    报警: You are running the esm-bundler build of vue-i18n. It is recommended to conf 解决: 在vue.config.js文 ...

  7. win10无管理员权限下以压缩包方式安装JDK8

    使用场景:如果在没有管理员权限的情况下,无法运行.exe文件,可以使用这种方式安装,本次把JDK安装到D:\jdk-8u152 一:获取JDK8的压缩包 1.JDK8 华为镜像地址 2.将下载好的ex ...

  8. MarkDown基本用法学习

    一级标题 语法:# +内容 二级标题1 语法:## +内容 二级标题2 三级标题 语法:### +内容 字体 加粗 语法:** +内容+ **(中间无空格) 效果:粗体 斜体 语法 * +内容+ *( ...

  9. springboot整合flowable-初步入门

    最近工作中有用到工作流的开发,引入了flowable工作流框架,在此记录一下springboot整合flowable工作流框架的过程,以便后续再次使用到时可以做一些参考使用,如果项目中有涉及到流程审批 ...

  10. Linux & 标准C语言学习 <DAY14>

    一.头文件     头文件可能会被任意源文件包含,意味着头文件中的内容可能会在多个目标文件中存在,要保证合并时不要冲突     重点:头文件只编写声明语句,不能有定义语句         1.头文件应 ...