第五章 函数
前言: 函数是一个命名的代码块,通过调用函数可以执行相应的代码。 1 用来实现特定任务 2 库函数
函数之间通过转递参数和返回值进行通信。
C++支持按值和按引用传递参数;
C++允许重载函数;
一.函数定义
返回类型 函数名(参数列表)
{
函数体(语句块)
}
参数列表 : 需要从外界获取什么
函数的结果 : 返回值
函数的操作数 : 参数
函数的参数列表不能省略,由逗号分隔的形参列表构成,每个形参类型之后跟一个可选的形参名字。
如果函数不返回任何结果,可以将其返回类型声明为void。
函数分类:
1 无参函数 2 有参函数 3 空函数
二.函数调用
函数名 (实参列表);
形参:函数定义中的参数。
实参:在调用函数是提供的数据
若实参类型与相应的形参类型不匹配,如果有可能,就会应用一个隐形的类型转换。
如:int a (int n)
{
···
}
当n取浮点数时,该实参能转换为整数类型。(自动取整)
简单应用: 用函数判断素数
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cmath>
usingnamespace std;
int ddd(int x);
int main()
{
int n;
cin>>n;
if(ddd(n)==1)
{cout<<"yes"<<n;}
else
{cout<<"no"<<n;}
return 0;
}
int
ddd(int x)
{
int t;
if(x==2)
{return 1;}
t=2;
while(t<=sqrt(x)&&x%t!=0) ++t;
if(x%t==0)
return 0;
else
return 1;
}
函数调用时完成的两项工作:
-
实参初始化函数对应的形参
-
将控制权转移可被调用的函数。
结束时return语句的两个作用:
-
返回return语句中的值(如果有的话)
-
将控制权从被调函数转移给主调函数。
三.函数声明:
函数在使用前必须声明。
(多次声明,一次定义)
函数名,函数返回类型和形参列表构成了函数原型。
函数原型规定了函数的接口;
函数声明说明了函数的接口;
四.参数传递
参数转递是指用函数调用的实参来初始化函数形参存储区的过程。
参数转递方式:1.传值2.传引用
( 1 )按值传递 :用实参值初始化形参
缺点:在被调用函数中,形参值可以改变,但不影响主调函数的实参值。参数传递方向只是从实参到形参,简称:单向值传递。
不适用情况:
·当大型的类对象或结构体变量作为参数按值传递时,为对象在运行栈中分配空间并复制对象的时间和空间开销往往够大。
如果要改变实参的值,(两种办法):
- 将参数声明为指针,用变量的地址实施调用。
(传值调用)
- 将参数声明为引用。
( 2 )按引用传递
按值传递时,函数操作的是实参的本地副本。
但参数是引用时,形参是实参的引用,函数操作的形参是实参的别名,因而可以改变实参的值。
引用参数的三种基本用途:
1.
通过传递引用在函数内修改实参的值。
2.
向主调函数返回格外的结果。
3.
向函数传递一个大型的结构体变量或类对象。
( 3 )数组参数
在c++中数组永远不会按值传递,数组做参数时,将传递数组第一个元素的地址,数组的长度与参数声明无关。
如: 下面三个声明是等价的;
-
void foo (int *a);
-
void foo (int a[ ]);
-
void foo (int a[ 10 ]);
五.返回类型和return语句
两种形式:
-
return;
-
return
表达式;注意: 不能返回自动局部对象的指针或引用。
六.函数重载
前言:几个不同的函数可以使用相同的名字;
有时需要定义一组函数,它们对不同类型的数据执行同样的一般性动作,表达相同的概念。
七.作用域和储存类型
生产期:指程序执行过程中对象存在的时间。
(对象的生产期与对象的作业域和储存类型密切相关)
作用域:程序的一段区域,名字的作业域指的是该名字可以在哪些程序文本区使用。
在函数外部定义的变量称为外部变量或全局变量;
在函数内部定义的变量称为内部变量或局部变量;
全局变量数组初始化全部为0;局部变量值是随机的,要初始化初值,局部变量受栈空间大小限制,大数组需要注意。
寄存器变量:用register声明,对编译器而言是一个建议。
局部对象:
- 自动对象
C++的函数会定义和使用一些局部变量,当执行函数时,为其中定义的局部变量分配空间,称为自动对象。如:函数的形参。
- 静态对象
需要在同一个函数两次调用之间保留某些数据。
可以将局部变量对象声明为static,这样的对象是静态储存的。