小猪猪C++笔记基础篇(六)参数传递、函数重载、函数指针、调试帮助
小猪猪C++笔记基础篇(六)
————参数传递、函数重载、函数指针、调试帮助
关键词:参数传递、函数重载、函数指针、调试帮助
因为一些事情以及自己的懒惰,大概有一个星期没有继续读书了,已经不行了,赶紧写一篇压压惊。把我文章抱走的同学留个言嘛。
函数在变成里面是一个非常重要的组成部分,那么这一部分我们先简单的介绍一下参数是如何传递进入函数,函数如何返回结果的。然后我们再来看看函数重载是个什么样的机制,最后在介绍一下所谓的函数指针到底是个什么东西。那么直接开始正题吧:
一、函数的参数传递
我们知道函数一般都长这样:
int fun(int a,int b);
一般由返回类型、函数名、参数类型组成。我们称它为函数原型。
每次调用函数的时候都会重新创建它的形参,并用传入的实参进行初始化,形参的初始化机理与变量的初始化一样。如果形参是引用类型,它将绑定要对应的实参上;否则将实参拷贝后赋值给形参。
当形参是引用类型的时候,我们称实参被引用传递,函数被传引用调用。简单的说,形参就是实参的别名。在函数内修改形参同时也会改变实参的值。
当实参的值是被拷贝给形参时,我们称实参被传值传递,函数被传传值调用。简单的说,形参和实参是两个相互独立的对象。在函数内修改形参,不会改变实参的值。
我们简单的用下面这一小段代码,来说明一下形参传值调用:
void reset(int *ip)
{
*ip=;
ip=;
}
这里reset的形参是一个指针,但是我们前面提到了,指针也是一种变量,所以ip是对传入指针的一个拷贝,指像同一个值,但是是不同的指针。
主函数简单的就写成这样。19、20行结果可以看书p指向n的地址,q指向i的地址。26行修改了n的值。那么关键来啦!37行i变成了0,那么我们再看看40行发生了什么。对的,p的值并没有变成0而是和输入的时候一样,但是*p,也就是p指向的值变成了0。
所以,我们需要用过形参修改实参的值是可以用指针形参的方法来做,但是形参的指针是一个新的指针,它指向的值和实参是一样的。
如果我们想要修改实参的值,最简单的办法就是引用调用了,因为引用就是实参的别名,可以把它就看成形参,想怎么弄就怎么弄。
引用主要的优点有两个:1、避免拷贝,可以节省许多空间,特别是在传递字符串的时候。2、使用引用形参返回额外信息。因为C++中函数只能返回一个值,当你需要返回很多值的时候,引用可以很好的解决这个问题。
引用做起来十分简单,只要你记住它就是实实参,它就是实参,它就是实参,重要的事情说三遍。
数组形参,由于数组不能拷贝并且我们使用数组的时候通常会转化成指针。因此我们无法以值传递的方式使用参数数组。我们为函数传递一个数组时,实际上传递的使指向数组首元素的指针。一般来说,指针数组会写成下面几个形式:
void fun(const int *); void fun(const int []); void fun(const int []);
由于数组是右指针形式传递给函数的,所以一开始函数并不知道数组的尺寸,管理指数形参通常有三种技术:
1、标记指定数组长度。简单的说就是在数组结尾的时候加一个标记,然后计算标记前有多少个数,这种用起来好麻烦。
2、显示传递一个表示数组大小的形参。把数组大小做为形参传递,这种方法比较常用。
3、数组引用形参。在此之前我很少碰到有这种方法的。就是对数组做一个引用,在这里mark一下:void fun(int (&arr)[10]);
另外在准备一些知识性的东西:
主函数一般都张这样:
int _tmain(int argc, _TCHAR* argv[])
其中argc是输入参数的个数,argv[]是字符串。例如,我们输入:test.exe hello。argc=2, argv[0]=”text.exe”,argv[1]=”hello”;
二、返回类型和return语句
return语句终止当前正在执行的函数,并将控制权返回调用该函数的地方。
返回一个值的方式和初始化一个变量或形参的方式完全一样,返回的值用于初始化调用点的一个临时量,该临时梁就是函数调用的结果。
注意:请不要返回局部对象的引用或者指针。因为函数完成后它所占用的存储空间将会被释放掉,也就是说意味着局部变量的引用将指向不在有效的区域。
递归函数,是一种很特殊的函数,它自己调用了自己,例如我们阶乘:
int factorial(int val) { if(val>) return factorial((val-))*val; else return ; }
递归函数需要有一个出口,否则将永远的递归下去。递归函数有时会简化我们的编程思路,但是如果递归层数太多会爆栈。一般刚刚学习的时候觉得能写递归程序简直牛逼的不行,但是实际操作中能不用递归尽量不要用递归,一般都用“栈”来替代递归。
返回数组指针。一般人都不会这么干吧,因为数组不能被拷贝,所以不能返回数组,但是可以返回数组指针或引用,如下给出,不再详述。
int (*func(int i))[10];
三、函数重载
重载函数是函数的一种特殊情况,为方便使用,C++允许在同一范围中声明几个功能类似的同名函数,但是这些同名函数的形式参数(指参数的个数、类型或者顺序)必须不同,也就是说用同一个运算符完成不同的运算功能。这就是重载函数。重载函数常用来实现功能类似而所处理的数据类型不同的问题。
如我们写文件的时候,数据不同,但是完成同样的功能:
void writeFile(char *cMaskName,char* pAllMask); void writeFile(char *cName,short* pAllMask);
调用的时候编译器会根据不同的参数类型选择最匹配的函数来调用,如果匹配出现错误和二义性会报错。具体可以参见这篇文章,写的非常的详细:
http://www.cnblogs.com/skynet/archive/2010/09/05/1818636.html
四、默认实参
某些函数有这样一种形成,在很多次调用的时候都被赋予相同一个值,此时我们把这个反复出现的值成为函数的默认实参。调用含有默认实参的函数时,可以包含该实参,也可以省略该实参。函数调用时参数按期位置解析,默认实参负责条目函数调用缺少的尾部实参。
五、内联函数
内联函数在前面的博客里面写过,这种函数只要的用途是可以提高程序的效率,但是会比较占内存。http://www.cnblogs.com/Dr-XLJ/p/4485424.html,当然了,内联函数这篇是抄的。
六、调试帮助
我认为这部分是非常的有用的,在写程序的时候想看看结果总是各种printf,然后交付的时候各种注释,超级麻烦。
具体做法是这样的:
如果我们没有定义NDEBUG,那么会执行16行内容,如果定义了NDEBUG就不会执行。
另外,预处理器定义了许多类似于“__FUNCDNAME__”的很有用的名字,对调试起到帮助。
七、函数指针
函数这个部分内容比较多,但是马上快完了。最后看看函数指针。
函数指针指向的是函数而非对象。和其他指针一样,函数指针指向某种特定的类型。函数的类型由它的返回类型和形参类型共同决定,与函数名无关。所以我们可以用同一个函数类型的函数指针指向不同名字的函数。
另外,我们不能把函数当做形参来调用,但是可以把函数指针当做形参来做。具体我们做一个简单的小例子:
int add(int a,int b){return a+b;} int sub(int a,int b){return a-b;} int mul(int a,int b){return a*b;} void show(int (*p)(int a,int b),int a,int b) { cout<<p(a,b)<<endl;
return; } int _tmain(int argc, _TCHAR* argv[]) { int (*p)(int a,int b)=;
int a=,b=; p=add;
show(p,a,b); p=sub;
show(p,a,b); p=mul;
show(p,a,b); }
定义了三个同样类型的函数add,sub,mul,加、减、乘。然后定义了一个含有指针函数形参的show函数用于显示计算的结果。高光的部分需要注意,第一个是函数指针作为形参的写法,第二个是函数指针的声明方法。我们分别把函数指针指向add,sub,mul,调用show函数发现显示出了不同的结果。
函数的指针在编程中是个非常有用的方法,不要害怕,多用用就OK了。
本次内容略多,不能只靠看理论就能掌握,需要在实践中多运用才能熟练的使用和掌握,写出漂亮的代码。
小猪猪C++笔记基础篇(六)参数传递、函数重载、函数指针、调试帮助的更多相关文章
- 小猪猪C++笔记基础篇(四)数组、指针、vector、迭代器
小猪猪C++笔记基础篇(四) 关键词:数组,Vector. 一.数组与指针 数组相信大家学过C语言或者其他的语言都不陌生,简单的就是同一个变量类型的一组数据.例如:int a[10],意思就是从a开始 ...
- 小猪猪C++笔记基础篇(五)表达式、语句
小猪猪C++笔记基础篇(五) 关键词:表达式.语句 本章的内容比较简单,基本上没有什么理解上的困难,都是知识上的问题.先开始想要不要写呢,本来是不准备写的,但是既然读了书就要做笔记,还是写一写,毕竟还 ...
- Python学习笔记基础篇——总览
Python初识与简介[开篇] Python学习笔记——基础篇[第一周]——变量与赋值.用户交互.条件判断.循环控制.数据类型.文本操作 Python学习笔记——基础篇[第二周]——解释器.字符串.列 ...
- JavaScript笔记基础篇(二)
基础篇主要是总结一些工作中遇到的技术问题是如何解决的,应为本人属于刚入行阶段技术并非大神如果笔记中有哪些错误,或者自己的一些想法希望大家多多交流互相学习. 1.ToFixed()函数 今天在做Birt ...
- java学习笔记-基础篇
Java基础篇 1—12 常识 13 this关键字 14参数传递 16 继承 17 访问权限 28—31异常 1—12 常识 1.文件夹以列表展示,显示扩展名,在地址栏显示全路径 2.javac编译 ...
- metasploit 渗透测试笔记(基础篇)
0x00 背景 笔记在kali linux(32bit)环境下完成,涵盖了笔者对于metasploit 框架的认识.理解.学习. 这篇为基础篇,并没有太多技巧性的东西,但还是请大家认真看啦. 如果在阅 ...
- Python学习笔记——基础篇【第一周】——变量与赋值、用户交互、条件判断、循环控制、数据类型、文本操作
目录 Python第一周笔记 1.学习Python目的 2.Python简史介绍 3.Python3特性 4.Hello World程序 5.变量与赋值 6.用户交互 7.条件判断与缩进 8.循环控制 ...
- Python学习笔记——基础篇【第四周】——迭代器&生成器、装饰器、递归、算法、正则表达式
目录 1.迭代器&生成器 2.装饰器 a.基本装饰器 b.多参数装饰器 3.递归 4.算法基础:二分查找.二维数组转换 5.正则表达式 6.常用模块学习 #作业:计算器开发 a.实现加减成熟及 ...
- SQL必学必会笔记 —— 基础篇
基础篇 SQL语言按照功能划分 DDL(DataDefinitionLanguage),也就是数据定义语言,它用来定义我们的数据库对象,包括 数据库.数据表和列.通过使用DDL,可以创建,删除和修改数 ...
随机推荐
- POJ 3461 Oulipo(模式串在主串中出现的次数)
题目链接:http://poj.org/problem?id=3461 题意:给你两个字符串word和text,求出word在text中出现的次数 思路:kmp算法的简单应用,遍历一遍text字符串即 ...
- eclipse maven SLF4J: Failed to load class org.slf4j.impl.StaticLoggerBinder
现象:运行eclipse maven build,console 有红色日志如下: SLF4J: Failed to load class "org.slf4j.impl.StaticLog ...
- 一周学会Mootools 1.4中文教程:序论
刚才发了几篇Mootools(以后直接简称Moo或Mt,看到这两个名字的时候不要感到奇怪),有一位热心的朋友"追杀"告诉我说现在已经出到1.4了,就不要再纠结于1.2了,想象一下有 ...
- A Byte of Python 笔记(9) 面向对象编程
第11章 面向对象编程 面向过程:根据操作数据的函数或语句块来设计程序. 面向对象(OOP, object-oriented programming):把数据和功能结合起来,用对象包裹组织程序. 类 ...
- Python开发环境Spyder安装方法
Spyder(Scientific PYthon Development EnviRonment)是一个强大的交互式 Python 语言开发环境,提供高级的代码编辑.交互测试.调试等特性,支持包括 W ...
- C单链表实现
/* * LinkNode.c * * Created on: Jan 14, 2014 * Author: root */ #include <stdlib.h> #include &l ...
- java时间验证工具
可以验证2014-02-21这种错误
- python 启动简单web服务器
有时我们在开发web静态页面时,需要一个web服务器来测试. 这时可以利用python提供的web服务器来实现. 1.在命令行下进入某个目录 2.在该目录下运行命令: python -m Simple ...
- HDU2577:How to Type(DP)
Problem Description Pirates have finished developing the typing software. He called Cathy to test hi ...
- SVN 让项目某些文件不受版本控制
@echo On @Rem 删除SVN版本控制目录 @PROMPT [Com] @for /r . %%a in (.) do @if exist "%%a\.svn" rd /s ...