C++学习笔记(七):函数

函数通用格式:

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=1, j=2;
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=3,j=5;
 9     swap(i,j);//调用函数swap
10     cout<<i<<" "<<j<<endl;//i和j的值未互换
11     return 0;
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=3,j=5;
 9     swap(&i,&j);//实参是变量的地址
10     cout<<i<<" "<<j<<endl;//i和j的值已互换
11     return 0;
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=3,j=5;
 9     swap(i,j);
10     cout<<"i="<<i<<" "<<"j="<<j<<endl;//i和j的值已互换
11     return 0;
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)返回引用,要求在函数的参数中,包含有以引用方式或指针方式存在的,需要被返回的参数。比如:

 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在函数名前面的时候修饰的是函数返回值,失去了左值的作用,但是省去拷贝,增加效率。

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

时间: 2024-11-05 06:51:14

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

C语言学习笔记(七) 函数指针

"函数指针"和"指针函数"是一对容易把人弄晕的概念,但我们只要把握好定语,倒也不难理解.这两个名词都是简称,"指针函数"是"返回值为指针的函数",而"函数指针"则是"指向函数的指针".这篇主要讲讲函数指针. 我们讲有int 指针,char指针,它们都是一个指针指向这个变量的实际地址.而C语言在编译函数的时候每个函数会有一个入口地址,当我们用一个指针指向这个入口地址,它就称为函数指针.有了

Lua学习笔记(七):迭代器与泛型for

1.迭代器与闭包 迭代器是一种支持指针类型的结构,它可以遍历集合的每一个元素.在Lua中我们常常使用函数来描述迭代器,每次调用该函数就返回集合的下一个元素. 迭代器需要保留上一次成功调用的状态和下一次成功调用的状态,也就是他知道来自于哪里和将要前往哪里.闭包提供的机制可以很容易实现这个任务.记住:闭包是一个内部函数,它可以访问一个或者多个外部函数的外部局部变量.每次闭包的成功调用后这些外部局部变量都保存他们的值(状态).当然如果要创建一个闭包必须要创建其外部局部变量.所以一个典型的闭包的结构包含

python学习笔记七:条件&循环语句

1.print/import更多信息 print打印多个表达式,使用逗号隔开 >>> print 'Age:',42 Age: 42   #注意个结果之间有一个空格符 import:从模块导入函数 import 模块 from 模块 import 函数 from 模块 import * 如果两个模块都有open函数的时候, 1)使用下面方法使用: module1.open()... module2.open()... 2)语句末尾增加as子句 >>> import ma

Swift学习笔记七:闭包

闭包可以 捕获 和存储其所在上下文中任意常量和变量的引用. Swift 会为您管理在 捕获 过程中涉及到的内存操作. 在 函数 章节中介绍的全局和嵌套函数实际上也是特殊的闭包,闭包采取如下三种形式之一: 1. 全局函数是一个有名字但不会捕获任何值的闭包 2. 嵌套函数是一个有名字并可以捕获其封闭函数域内值的闭包 3. 闭包表达式是一个可以捕获其上下文中变量或常量值的没有名字的闭包 一.闭包表达式 闭包函数类似于Objective-C中的block.下面我们用事实说话: let counts =

Linux System Programming 学习笔记(七) 线程

1. Threading is the creation and management of multiple units of execution within a single process 二进制文件是驻留在存储介质上,已被编译成操作系统可以使用,准备执行但没有正运行的休眠程序 进程是操作系统对 正在执行中的二进制文件的抽象:已加载的二进制.虚拟内存.内核资源 线程是进程内的执行单元 processes are running binaries, threads are the smal

MySQL学习笔记-自定义函数

MySQL学习笔记-自定义函数 1.自定义函数简介 自定义函数:用户自定义函数(user-defined function,UDF)是一种对MySQL扩展的途径,其用法与内置函数相同 自定义函数的两个必要条件:(1)参数  (2)返回值 自定义函数: 创建自定义函数 CREATE FUNCTION function_name RETURNS {STRING|INTEGER|REAL|DECIMAL} routine_body 关于函数体: 1.函数体可以由合法的SQL语句构成: 2.函数体可以是

第十七篇:博采众长--初探WDDM驱动学习笔记(七)

基于WDDM驱动的DirectX视频加速重定向框架设计与实现 现在的研究生的论文, 真正质量高的, 少之又少, 开题开得特别大, 动不动就要搞个大课题, 从绪论开始到真正自己所做的内容之间, 是东拼西凑地抄概念, 抄公式, 达到字数篇幅的要求, 而自己正真做了什么, 有哪些实际感受, 做出的内容, 相比前面的东拼西凑就几点内容, 之后就草草结束, 步入感谢的段落. 原因不光只有学生自己, 所谓的读研, 如果没有一个环境, 学生有再大的愿望, 再强的毅力, 到头来也只是空无奈. 有些导师要写书,

马哥学习笔记七——LAMP编译安装之MYSQL

1.准备数据存放的文件系统 新建一个逻辑卷,并将其挂载至特定目录即可.这里不再给出过程. 这里假设其逻辑卷的挂载目录为/mydata,而后需要创建/mydata/data目录做为mysql数据的存放目录. 2.新建用户以安全方式运行进程: # groupadd -r mysql # useradd -g mysql -r -s /sbin/nologin -M -d /mydata/data mysql # chown -R mysql:mysql /mydata/data 3.安装并初始化my

python学习笔记之函数总结--高阶函数以及装饰器

python学习笔记之函数总结--高阶函数以及装饰器 Python特点: 1.不是纯函数式编程(允许变量存在): 2.支持高阶函数(可以传入函数作为变量): 3.支持闭包(可以返回函数): 4.有限度的支持匿名函数: 高阶函数: 1.变量可以指向函数: 2.函数的参数可以接收变量: 3.一个函数可以接收另一个函数作为参数: 下面我将示例一些函数的写法以及使用,并说明python中函数的特性: 1.基本的高阶函数示例: #!/usr/bin/env python def func():      

swift学习笔记(七)自动引用计数

与Object-c一样,swift使用自动引用计数来跟踪并管理应用使用的内存.当实例不再被使用时,及retainCount=0时,会自动释放是理所占用的内存空间. 注:引用计数仅适用于类的实例,因为struct和enumeration属于值类型,也就不牵涉引用,所以其存储和管理方式并不是引用计数. 当一个实例被初始化时,系统会自动分配一定的内存空间,用于管理属性和方法.当实例对象不再被使用时,其内存空间被收回. swift中的引用类型分为三种,即Strong强引用,weak弱引用和无主引用unw