C++学习基础十六-- 函数学习笔记
C++ Primer 第七章-函数学习笔记
一步一个脚印、循序渐进的学习。
一、参数传递
- 每次调用函数时,都会重新创建函数所有的形参,此时所传递的实参将会初始化对应的形参。
- 「如果形参是非引用类型,则复制实参的值来初始化形参;如果形参是引用类型,则形参只是实参的别名。」
- 「非引用形参表示对实参的局部副本,函数内修改此类型形参时仅仅改变局部副本的值,一旦函数执行结束,这些局部变量的值就没有了,因此不影响实参的值。」
- 「如果函数参数为指针,同样形参是实参的副本,修改形参指针的值不影响实参,但是如果修改形参指针所指向的值则会影响实参。」
void reset1(int *p)
{
*p = ;//修改形参所指向的值,则实参所指向的值也会改变,变为0
} void reset2(int *p)
{
p = ;//仅修改形参值,不影响实参值,即实参还是原来的地址,而形参的地址变为0
} void main()
{
int i = ;
reset1(&i);
printf("i = %d \n",i);// i = 0 i = ;
reset2(&i);
printf("i = %d \n",i); // i = 2
}
- 「如果想要保护指针指向的值,则需要将指针定义为const,表示当前指针所指向的值可读不可写。」
void reset3(const int *p)
{
p = ;//ok
*p = ;//error,不允许修改p所指向的值
}
- 可以用非const指针初始化const指针,但不允许使用const指针初始化非const指针。例如:
int i = ;
const int *p1 = &i;//ok, 非const指针初始化const指针
int p2 = p1;//error, 不能用const指针初始化非const指针,报语法错误
- 当函数的参数是非引用(或非指针)非const的类型时,在调用该函数时,实参既可以是const类型的,也可以是非const类型的。
如果需要在函数内部修改实参值,则需要将形参定义为引用或者指针。
const修饰变量,表示该变量不可修改,这是对于基本数据类型而言。对于指针来说,有两种情况:
int num = ;
int num2 = ;
const int *p1 = #// *p1 = 20 不允许修改
int * const p2 = #// p2 = &num2 不允许
- 第三行这种写法表示p1所指向的值是const类型的,不允许修改其所指向的值。
- 第四行这种写法表示p2这个指针是const类型的,不允许给该指针重新赋值。
- 指向指针的引用
写法:int *&p1
从右向左理解,表示p1是一个引用,与该引用绑定的是一个int型的指针。
这种写法一般常用函数的参数,
举例说明:实现一个函数,该函数的功能是交换两个参数的值。
这有三种方法:
- 第一种方法:传递int型指针
这种情况下,形参复制实参的值,此时两者的地址值相同,即指向相同的对象。此时只是修改了指针所指向地址中的值,而并未改变指针值。
void TransNums(int *p1, int *p2)
{
int nTmp = (*p1);
*p1 = *p2;
*p2 = nTmp;
} void main()
{
int num = ;
int *p2 = #
int numP3 = ;
int *p3 = &numP3; printf("未交换-指针值:p2 = %d, p3 = %d num = %d numP3 = %d\n", *p2, *p3,num,numP3);
TransNums(p2, p3);
printf("交换-指针的值:p2 = %d, p3 = %d num = %d numP3 = %d\n", *p2, *p3,num,numP3);
}
打印结果:
未交换-指针值:p2 = 10, p3 = 30 num = 10 numP3 = 30
交换-指针的值:p2 = 30, p3 = 10 num = 30 numP3 = 10
「表示修改了指针所指向的值,而并未改变指针」
- 第二种方法:传递int性引用
形参是实参的别名,等同于实参。
void TransNumsRef(int &num1, int &num2){
int nTmp = num1;
num1 = num2;
num2 = nTmp;
}
void main()
{
int num = ;
int numP3 = ;
printf("未交换-实参值:num = %d, numP3 = %d\n", num, numP3);
TransNumsRef(num, numP3);
printf("交换-实参的值:num = %d, numP3 = %d\n", num, numP3);
}
打印结果:
未交换-实参值:num = 10, numP3 = 30
交换-实参的值:num = 30, numP3 = 10
- 第三种方法:传递指针引用参数
此时形参为引用,指向指针,这种情况下修改了指针,即指针的值(或地址)改变了
void TransNumsPRef(int *&p1, int *&p2)
{
int *pTmp = p1;
p1 = p2;
p2 = pTmp;
} void main()
{
int num = ;
int *p2 = #
int numP3 = ;
int *p3 = &numP3;
printf("未交换-指针引用值:p2 = %d, p3 = %d num = %d numP3 = %d\n", *p2, *p3,num,numP3);
TransNumsPRef(p2, p3);
printf("交换-指针引用的值:p2 = %d, p3 = %d num = %d numP3 = %d\n", *p2, *p3,num,numP3);
}
打印结果:
未交换-指针引用值:p2 = 10, p3 = 30 num = 10 numP3 = 30
交换-指针引用的值:p2 = 30, p3 = 10 num = 10 numP3 = 30
- 几种常见的表示形式:
int &arr[]--- 表示arr是一个引用数组,即arr一个数组,数组的每个元素是int类型的引用
int (&arr)[]--表示arr是一个数组的引用,数组的每个元素是int类型变量
int *arr[]----表示arr是一个指针数组,即arr是一个数组,每个元素是一个int型指针
int (*arr)[]--表示arr是一个数组的指针,即该指针指向一个数组,数组的每个元素是int变量,等同于int (arr*)[]
二、函数声明
默认实参
声明一个函数时,我们可以给定形参的默认值,这种用法就是默认实参。如果有一个或多个形参具有默认实参,那么它后面的所有形参都必须有默认实参。
一般而言,具有默认实参的形参放在参数列表的后面。应该在函数声明中提供默认实参。如果在函数定义的形参列表中提供默认实参,那么只有在包含该函数定义的源文件中调用,其默认实参才有效。
三、内联函数
- 优点:
- 减少函数调用的开销。将函数定义为内联函数,就是在程序中每个调用点上“内联的”展开。
- 注意事项:
- 不同于其他函数,内联函数定义必须在头文件中实现。
四、重载函数
重载函数:函数名相同,参数列表不同的函数。
函数名与参数列表完全相同,返回值类型不同的不能成为函数重载。即函数重载不能依赖于返回值类型。
重载和const参数:仅当形参是引用或指针时,形参是否为const才有影响。
几种情况并举例说明:
- 基于函数的引用形参是否为const实现函数重载
void lookat(int &a);
void lookat(const int &a);//新函数,即函数重载
「如果形参为非const引用,则函数调用时,不能将const类型的实参传递过来;如果传递了const对象,则必须调用带有const形参的函数。」
「如果形参为const引用,则函数调用时,既可以传递const对象,也可以传递非const对象。」
- 基于函数的指针形参是否指向const对象实现函数重载
void func(int *p);
void func(const int *p);//新函数,指向const对象
「如果形参为指向const对象的指针,则函数调用时,实参既可以是指向const对象的指针,也可以是指向非const对象的指针。」
「如果两个函数仅在指针形参是否指向const对象不同,则指向非const对象的指针形参对于指向非const对象的实参来说是最佳匹配。」
- 不能基于指针本身是否是const类型重载函数
void foo(int *p);
void foo(int * const p);//重复声明
C++学习基础十六-- 函数学习笔记的更多相关文章
- GUI学习之十六——QSpinBox学习总结
我们在上一章讲了步长调节器QAbstractSpinBox,这一节来讲一下它的一个子类:QSpinBox 一.描述 QSpinBox是一个主要处理整数和离散值集合的步长调节器控件,它允许用户通过单击增 ...
- 学习笔记:CentOS7学习之十六:LVM管理和ssm存储管理器使用
目录 学习笔记:CentOS7学习之十六:LVM管理和ssm存储管理器使用 16.1 LVM的工作原理 16.1.1 LVM常用术语 16.1.2 LVM优点 16.2 创建LVM的基本步骤 16.2 ...
- 201871010104-陈园园《面向对象程序设计(java)》第十六周学习总结
201871010104-陈园园<面向对象程序设计(java)>第十六周学习总结 项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ ...
- 201871010105-曹玉中《面向对象程序设计(java)》第十六周学习总结
201871010105-曹玉中<面向对象程序设计(java)>第十六周学习总结 项目 内容 这个作业属于哪个过程 https://www.cnblogs.com/nwnu-daizh/ ...
- 风炫安全Web安全学习第十六节课 高权限sql注入getshell
风炫安全Web安全学习第十六节课 高权限sql注入getshell sql高权限getshell 前提条件: 需要知道目标网站绝对路径 目录具有写的权限 需要当前数据库用户开启了secure_file ...
- 201771010134杨其菊《面向对象程序设计(java)》第十六周学习总结
第十六周学习总结 第一部分:理论知识 1. 程序是一段静态的代码,它是应用程序执行的蓝本.进程是程序的一次动态执行,它对应了从代码加载.执行至执行完毕的一个完整过程.操作系统为每个进程分配一段独立的内 ...
- 201671010140. 2016-2017-2 《Java程序设计》java学习第十六周
java学习第十六周-并发 本周,学习了Java中线程,并发的知识,在老师的带领下,进行了对知识的理解学习,以及对实验的运行讲解,对这一块内容掌握的还可以,在自主编程中,也能够完成.线, ...
- 201871010123-吴丽丽 《面向对象程序设计(Java)》第十六周学习总结
201871010123-吴丽丽 <面向对象程序设计(Java)>第十六周学习总结 项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ ...
- 201271050130-滕江南-《面向对象程序设计(java)》第十六周学习总结
201271050130-滕江南-<面向对象程序设计(java)>第十六周学习总结 博文正文开头格式:(2分) 项目 内容 这个作业属于哪个课程 https://www.cnblogs.c ...
随机推荐
- 阶段01Java基础day18集合框架04
18.01_集合框架(Map集合概述和特点) A:Map接口概述 查看API可以知道: 将键映射到值的对象 一个映射不能包含重复的键 每个键最多只能映射到一个值 B:Map接口和Collection接 ...
- JavaScript 之 DOM
1. DOM DOM:Document Object Model 文档对象模型,定义访问和操作结构化文档(HTML)的方式. 在 HTML DOM (Document Object Model) 中 ...
- Java学习笔记36(jdbc快速入门)
JDBC: Java DataBase Connectivity 是java程序连接存取数据库的应用程序接口 (是sun公司的程序员定义的一套操作数据库的规则,然后下面的各个公司如:mysql,sql ...
- 蓝牙协议分析(11)_BLE安全机制之SM
1. 前言 注1:此SM是Security Manager的缩写,非彼SM,大家不要理解歪了! 书接上文,我们在“蓝牙协议分析(10)_BLE安全机制之LE Encryption”中介绍了BLE安全机 ...
- 新建一个self hosted Owin+ SignalR Project(2)
ASPNET SignalR是为ASP.NET开发人员提供的一个库,可以简化开发人员将实时Web功能添加到应用程序的过程.实时Web功能是指这样一种功能:当所连接的客户端变得可用时服务器代码可以立即向 ...
- C#中关于对out和ref的认识
1.两者都是按照地址进行传递的.2.ref关键字是的参数按照引用传递的方式进行.他的效果是控制权传递会调用方法是,可以对这个参数进行修改 要使用ref参数,那么方法的定义和调用方法都必须进行显示的 ...
- File类相关操作
1.File类常见方法: 创建: boolean createNewFile():在指定位置创建文件 如果该文件已经存在,则不创建,返回false,和输出流不一样,输出流对象一建立就创立文件,而且文件 ...
- IDEA java编译中出现了Exception in thread “main" java.lang.UnsupportedClassVersionError
这个问题确实是由较高版本的JDK编译的java class文件试图在较低版本的JVM上运行产生的错误. 在idea中需要修改的有两区,四个地方 1. 修改项目编译器 Crtl+Shift+A 进入如下 ...
- # 20175120 2018.3.3 《Java程序设计》第1周学习总结
## 教材学习内容总结 1.安装ubuntu,在实验楼学习liunx系统各种功能的实现.2.在ubuntu平台上进行java程序的编写3.学会使用JDB调试java程序,并将代码上传到码云上4.学习j ...
- 如何在Linux系统下挂载光盘
工具/原料 Linux 方法/步骤 找到光盘的完整路径名.在命令行输入:ls -l /dev | grep cdrom. 可以看到光盘的名字叫做:cdrom1.然后在命令行执行: mount /d ...