函数通用格式:

  1. typeName functionName(parameterList)
  2. {
  3. //statements
  4. return value;//value is type cast to type typeName
  5. }

函数原型:

C++的函数必须提供一个函数原型;

  1. int add(int a, int b);//函数原型
  2. int add(int, int);//也可以省略掉参数名称
  3.  
  4. //函数定义
  5. int add(int a, int b)
  6. {
  7. return a + b;
  8. }

函数参数详解

形参和实参:

  1. void add(int a, int b)
  2. {
  3. int c = a + b;
  4. cout << c;
  5. }
  6.  
  7. void main()
  8. {
  9. int i=, j=;
  10. add(i, j);
  11. }

上面的示例中a和b是形参,i和j是实参。

参数传递:

C++中存在3种参数传递的方式;

(1)值传递

这时传给形参的是变量的值,传递是单向的。如果在执行函数期间形参的值发生变化,并不传回给实参。因为在调用函数时,形参和实参不是同一个存储单元。

  1. #include <iostream>
  2.  
  3. using namespace std;
  4.  
  5. int main()
  6. {
  7. void swap(int,int);//函数声明
  8. int i=,j=;
  9. swap(i,j);//调用函数swap
  10. cout<<i<<" "<<j<<endl;//i和j的值未互换
  11. return ;
  12. }
  13.  
  14. void swap(int a,int b)//企图通过形参a和b的值互换,实现实参i和j的值互换
  15. {
  16. int temp;
  17. temp=a;//以下3行用来实现a和b的值互换
  18. a=b;
  19. b=temp;
  20. }

(2)指针传递

形参是指针变量,实参是一个变量的地址,调用函数时,形参(指针变量)指向实参变量单元。

这种虚实结合的方法仍然是“值传递”方式,只是实参的值是变量的地址而已。通过形参指针变量访问主函数中的变量(i和j),并改变它们的值。这样就能得到正确结果,但是在概念上却是兜了一个圈子
,不那么直截了当。

  1. #include <iostream>
  2.  
  3. using namespace std;
  4.  
  5. int main()
  6. {
  7. void swap(int *,int *);//函数声明
  8. int i=,j=;
  9. swap(&i,&j);//实参是变量的地址
  10. cout<<i<<" "<<j<<endl;//i和j的值已互换
  11. return ;
  12. }
  13.  
  14. void swap(int *p1,int *p2)//形参是指针变量
  15. {
  16. int temp;
  17. temp=*p1;//以下3行用来实现a和b的值互换
  18. *p1=*p2;
  19. *p2=temp;
  20. }

(3)引用传递

参数变为实参的一个别名,形参和实参都是同一个对象;就和Java语言的非基元数据类型参数效果一致,使用比指针传递更加方便;

  1. #include <iostream>
  2.  
  3. using namespace std;
  4.  
  5. int main()
  6. {
  7. void swap(int &,int &);
  8. int i=,j=;
  9. swap(i,j);
  10. cout<<"i="<<i<<" "<<"j="<<j<<endl;//i和j的值已互换
  11. return ;
  12. }
  13.  
  14. void swap(int &a,int &b)//形参是引用类型
  15. {
  16. int temp;
  17. temp=a;
  18. a=b;
  19. b=temp;
  20. }

函数参数使用const修饰:

表示函数体中不能修改参数的值(包括参数本身的值或者参数其中包含的值)。

  1. void function(const int Var); //传递过来的参数在函数内不可以改变(无意义,因为Var本身就是形参)
  2.  
  3. void function(const char* Var); //参数指针所指内容为常量不可变
  4.  
  5. void function(char* const Var); //参数指针本身为常量不可变(也无意义, 因为char* Var也是形参)
  6.  
  7. void function(const Class& Var);//引用参数在函数内不可以改变
  8.  
  9. void function(const TYPE& Var); //引用参数在函数内为常量不可变

函数返回详解

主函数main的返回值:

这里提及一点,返回0表示程序运行成功。

返回非引用类型:

函数的返回值用于初始化在跳用函数出创建的临时对象。用函数返回值初始化临时对象与用实参初始化形参的方法是一样 的。如果返回类型不是引用,在调用函数的地方会将函数返回值复制给临时对象。
且其返回值既可以是局部对象,也可以是求解表达式的结果。

返回指针类型:

函数可以返回某种对象的内存地址即指针。

  1. float *func()
  2. {
  3. float *buf = new float[];
  4. return buf;
  5. }

返回引用:

当函数返回引用类型时,没有复制返回值。相反,返回的是对象本身。

返回引用的注意事项:

(1)返回引用,要求在函数的参数中,包含有以引用方式或指针方式存在的,需要被返回的参数。比如:

  1. int& abc(int a, int b, int c, int& result)
  2. {
  3. result = a + b + c;
  4. return result;
  5. }
  6. //这种形式也可改写为:
  7. int& abc(int a, int b, int c, int *result)
  8. {
  9. *result = a + b + c;
  10. return *result;
  11. }
  12. //但是,如下的形式是不可以的:
  13. int& abc(int a, int b, int c)
  14. {
  15. return a + b + c;
  16. }

(2)千万不要返回局部对象的引用。当函数执行完毕时,将释放分配给局部对象的存储空间。此时,对局部对象的引用就会指向不确定的内存。如:

  1. const string &manip(const string &s)
  2. {
  3. string ret = s;
  4. return ret;//wrong:returning reference to a local object
  5. }

函数和const详解

  1. const int foo(int a);
  2. const int foo(int a) const;

当const在函数名前面的时候修饰的是函数返回值,失去了左值的作用,但是省去拷贝,增加效率。

在函数名后面表示是常成员函数,该函数不能修改对象内的任何成员,只能发生读操作,不能发生写操作。

内联函数

内联函数使用inline进行标记,表示该函数最终在程序中会被复制到调用的地方,而不是作为函数进行调用,从而获得效率的提升。

注意:具有循环和switch语句的函数不能作为内联函数。

C++学习笔记(七):函数的更多相关文章

  1. python学习笔记(七)-函数

    函数 方法 功能说白了,函数就是把一堆代码组合到一起,变成一个整体.函数不调用不会被执行.作用在于提高代码的复用性.定义函数 def greet_user(): """关 ...

  2. Go语言学习笔记七: 函数

    Go语言学习笔记七: 函数 Go语言有函数还有方法,神奇不.这有点像python了. 函数定义 func function_name( [parameter list] ) [return_types ...

  3. (转)Qt Model/View 学习笔记 (七)——Delegate类

    Qt Model/View 学习笔记 (七) Delegate  类 概念 与MVC模式不同,model/view结构没有用于与用户交互的完全独立的组件.一般来讲, view负责把数据展示 给用户,也 ...

  4. Typescript 学习笔记七:泛型

    中文网:https://www.tslang.cn/ 官网:http://www.typescriptlang.org/ 目录: Typescript 学习笔记一:介绍.安装.编译 Typescrip ...

  5. 【opencv学习笔记七】访问图像中的像素与图像亮度对比度调整

    今天我们来看一下如何访问图像的像素,以及如何改变图像的亮度与对比度. 在之前我们先来看一下图像矩阵数据的排列方式.我们以一个简单的矩阵来说明: 对单通道图像排列如下: 对于双通道图像排列如下: 那么对 ...

  6. Linux学习笔记(七) 查询系统

    1.查看命令 (1)man 可以使用 man 命令名称 命令查看某个命令的详细用法,其显示的内容如下: NAME:命令名称 SYNOPSIS:语法 DESCRIPTION:说明 OPTIONS:选项 ...

  7. go微服务框架kratos学习笔记七(kratos warden 负载均衡 balancer)

    目录 go微服务框架kratos学习笔记七(kratos warden 负载均衡 balancer) demo demo server demo client 池 dao service p2c ro ...

  8. Java IO学习笔记七:多路复用从单线程到多线程

    作者:Grey 原文地址:Java IO学习笔记七:多路复用从单线程到多线程 在前面提到的多路复用的服务端代码中, 我们在处理读数据的同时,也处理了写事件: public void readHandl ...

  9. Matlab学习笔记 figure函数

    Matlab学习笔记 figure函数 matlab中的 figure 命令,能够创建一个用来显示图形输出的一个窗口对象.每一个这样的窗口都有一些属性,例如窗口的尺寸.位置,等等.下面一一介绍它们. ...

  10. matlab学习笔记 bsxfun函数

    matlab学习笔记 bsxfun函数 最近总是遇到 bsxfun这个函数,前几次因为无关紧要只是大概看了一下函数体去对比结果,今天再一次遇见了这个函数,想想还是有必要掌握的,遂查了些资料总结如下. ...

随机推荐

  1. Hbase二级索引

    http://blog.sina.com.cn/s/blog_4a1f59bf01018apd.html

  2. NuGet相关的文章

    NuGet学习笔记(1)——初识NuGet及快速安装使用http://www.cnblogs.com/zhwl/p/3377510.html NuGet学习笔记(2) 使用图形化界面打包自己的类库ht ...

  3. php实现自动运行文件

    autoexec.php <?php ignore_user_abort(); //即使Client断开(如关掉浏览器),PHP脚本也可以继续执行. set_time_limit(30); // ...

  4. JavaScript DOM高级程序设计 4.3控制事件流和注册事件侦听器--我要坚持到底!

    一.事件流 我们通过下面一个实例,进行说明. <body> <h1>Event Flow</h1> <ul id="nav"> &l ...

  5. Android开发之异步消息处理机制Handler

    更加详细的介绍Handler的博文-http://blog.csdn.net/guolin_blog/article/details/9991569 Android中的异步消息处理主要有四个部分组成, ...

  6. 让ie6支持fixed最简单和实用的方法

    <!DOCTYPE HTML> <html lang="en-US"> <head> <meta charset="UTF-8& ...

  7. BZOJ2668: [cqoi2012]交换棋子

    题解: 可以戳这里:http://www.cnblogs.com/zig-zag/archive/2013/04/21/3033485.html 其实自己yy一下就知道这样建图的正确性了. 感觉太神奇 ...

  8. 设计模式Day01

    一.工厂模式 1.工厂模式的关键点就是如何描述好这两个角色之间的关系,分为四种情况: (1)单一产品系,工厂生产一种类型的产品: (2)多产品系,特征相同.工厂生产多种类型的产品: (3)多产品系,部 ...

  9. SharePoint 2010 使用自定义aspx页面替换列表默认的新建(NewForm.aspx),查看(DispForm.aspx)和编辑(EditForm.aspx)页面

    转:http://www.cnblogs.com/sygwin/archive/2011/11/04/2236678.html 如何使用自定义的aspx页(比如Application Page)替换列 ...

  10. AM335x(TQ335x)学习笔记——挂载Ramdisk

    上篇文章中我们已经能够通过u-boot启动内核了,但是没有能够启动成功,从内核的log中可以看出,内核启动失败的原因是没有挂载到root文件系统,本文将使用busybox制作根文件系统并打包成ramd ...