目标
- 掌握C++中函数的声明与定义
- 熟练掌握函数的参数,原型和返回值,以及如何在程序中调用函数
了解C++中函数的重载
定义函数
函数的概述
定义函数
函数定义形式
返回类型 函数名(参数列表)
{
函数体
}
C++不允许函数定义嵌套应用示例
// lianxi.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include<iostream>
#include <iomanip>
using namespace std;
int func(int n)
{
if(n>0)
return 1;
else if(n==0)
return 0;
else
return -1;
}
int _tmain(int argc, _TCHAR* argv[])
{
int n;
cout<<"Please input n:"<<endl;
cin>>n;
cout<<"\nthe result:"<<func(n)<<endl;//调用函数func
getchar();
getchar();
return 0;
}
## 函数参数及原型 ##
函数原型也称为函数声明或函数模型。
函数的参数及返回值
int func(int n)//int n形参
cout<<"\nthe result:"<<func(n)<<endl;//调用函数func n为实际参数
函数原型
函数原型声明用来指出函数的名称,类型和参数,一般形式为
[<属性说明>]<函数类型><函数名>(<参数>)
- 属性说明可以默认,一般为inline(内联函数)、static(静态函数)、virtual(虚函数)、friend(友元函数)等这几个关键词之一
- 函数类型是指函数返回值的类型
- 函数名是一个C++标识符
参数,也称为形式参数,要求形式参数在函数原型声明、定义和调用时数据类型、个数,顺序一致,各形参名可以不同
main()函数
所有完整可运行的C++程序都必须有一个唯一的main()函数。
最简单的形式:
main()
{
变量声明语句
执行语句
}
#include "stdafx.h"
#include<iostream>
#include <iomanip>
using namespace std;
const double PI=3.1415;
double fcir_l(double);
double fcir_s(double);
int _tmain(int argc, _TCHAR* argv[])
{
double radius,cir_l,cir_s;
cout<<"please input radius:"<<endl;
cin>>radius;
cir_l=fcir_l(radius);
cout<<"the week long is:"<<"\t"<<cir_l<<endl;
cir_s=fcir_s(radius);
cout<<"the area is:"<<"\t"<<cir_s<<endl;
getchar();
getchar();
return 0;
}
double fcir_l(double r)
{
double cir_l;
cir_l=2*PI*r;
return cir_l;
}
double fcir_s(double r)
{
double cir_s;
cir_s=PI*r*r;
return cir_s;
}
带参数的main()函数
main函数中允许带两个参数
- argc,整型数据类型,表示命令行中字符串的个数。
- 指向字符型的指针数组argv[],
声明格式
int main(int argc,char *argv[ ])
调用函数
调用一个函数时,第一步是参数传递,第二步是函数体执行,第三步是返回,即返回到函数调用表达式的位置
函数调用格式
<函数名>(<实参表>)
传值调用
根据参数传递方式,函数调用分为按值传递和地址传递或引用传递。
传值调用即其参数是按值传递方式进行的。
过程:
1. 计算出实参表达式的值,接着给对应的形参变量分配一个存储空间中,该空间的大小等于该形参类型的长度
2. 把已求出的实参表达式的值一一存入到为形参变量分配的存储空间中,成为形参变量的初值,供被调用函数执行时使用。
// lianxi.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include<iostream>
#include <iomanip>
using namespace std;
void swap(int a,int b);
int _tmain(int argc, _TCHAR* argv[])
{
int x=8,y=10;
cout<<"x="<<x<<" y="<<y<<endl;
swap(x,y);
cout<<"x="<<x<<" y="<<y<<endl;
getchar();
return 0;
}
void swap(int a,int b)
{
int t;
t=a;
a=b;
b=t;
}
引用调用
以引用作为参数,既能完成传值调用,又使函数调用显得方便自然。
应用传递的方式是在函数定义时在形参前面加上引用运算符“&”
// lianxi.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include<iostream>
#include <iomanip>
using namespace std;
void swap(int &a,int &b);
int _tmain(int argc, _TCHAR* argv[])
{
int x=8,y=10;
cout<<"x="<<x<<" y="<<y<<endl;
swap(x,y);
cout<<"x="<<x<<" y="<<y<<endl;
getchar();
return 0;
}
void swap(int &a,int &b)
{
int t;
t=a;
a=b;
b=t;
}
增加了&符号即代表该函数被调用时采用的是引用调用,传递给函数的是实参的地址,因此,能够实现交换功能。
嵌套调用
在使用时,允许函数的嵌套
递归调用
函数的递归调用,即一个函数直接或间接的调用自身。
递归调用的执行需要两个步骤:
1. 递推:将一个复杂问题分解为一个相对简单且可直接求解的子问题。
2. 回归:这个子问题的结果逐层进行回代求值。
// lianxi.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include<iostream>
#include <iomanip>
using namespace std;
int Fac(int n)
{
if(n<0)
{
cout<<"error"<<endl;
return(-1);
}
else if(n<=1)
return(1);
else
return (n*Fac(n-1));//递归调用自身
}
int _tmain(int argc, _TCHAR* argv[])
{
int Fac(int n);
int n;
cout<<"input n"<<endl;
cin>>n;
cout<<"n!="<<Fac(n)<<endl;//调用函数
getchar();
getchar();
return 0;
}
void swap(int &a,int &b)
{
int t;
t=a;
a=b;
b=t;
}
带默认形参值的函数
只有当函数没有声明时,才可以在函数定义中指定形参的默认值。默认值的定义必须遵守从右到左的顺序,如果某个形参没有默认值,则它左边的参数就不能有默认值。
变量的作用域
一个程序将操作系统分配给其运行的内存块分为4块
- 代码区,存放程序的代码,即程序中各个函数中的代码块
- 全局数据区,存放程序全局数据和静态数据
- 堆区,存放程序的动态数据。
栈区,存放程序的局部数据,即各个函数中的数据
根据变量的作用域可以分为局部变量和全局变量局部变量
// lianxi.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include<iostream>
#include <iomanip>
using namespace std;
void swap(int a,int b);//函数原型的声明
int _tmain(int argc, _TCHAR* argv[])
{
int x=8,y=10;
int t=0;
cout<<"x="<<x<<" y="<<y<<endl;
swap(x,y);
cout<<"x="<<x<<" y="<<y<<endl;
cout<<"t in main is:"<<t<<endl;
getchar();
getchar();
return 0;
}
void swap(int a,int b)
{
int t;
t=a;
a=b;
b=t;
cout<<"t in swap is"<<t<<endl;
}
全局变量
// lianxi.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include<iostream>
#include <iomanip>
using namespace std;
int s1,s2,s3;
int vs(int a,int b,int c)
{
int v;
v=a*b*c;
s1=a*b;
s2=b*c;
s3=a*c;
return v;
}
int _tmain(int argc, _TCHAR* argv[])
{
int v,l,w,h;
cout<<"please input length,width and height:"<<endl;
cin>>l>>w>>h;
v=vs(l,w,h);
cout<<"v= "<<v<<endl;
cout<<"s1= "<<s1<<endl;
cout<<"s2= "<<s2<<endl;
cout<<"s3= "<<s3<<endl;
getchar();
getchar();
getchar();
return 0;
}
外部变量的一般形式
extern 数据类型 外部变量【,外部变量2……】;
函数的作用域
// lianxi.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include<iostream>
#include <iomanip>
using namespace std;
void fn()
{
goto S;//跳转到标号S
int b;
cin>>b;
if(b>0)
{
S: //定义标号
goto End;//跳转到end
}
End:
cout<<"Can't input b"<<endl;
}
int _tmain(int argc, _TCHAR* argv[])
{
fn();
getchar();
getchar();
return 0;
}
函数重载
函数重载是指同一个函数名可以对应着多个函数的实现,每一类实现对应着一个函数体,这些函数的名字相同,但是函数的参数的类型不同。
函数的重载
同一个函数名对应着多个不同的函数。“不同”是指这些函数的形参表必须互不相同,或者是形参的个数不同,或者是形参的类型不同,或者是两者都不相同,否则将无法实现函数重载。
// lianxi.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include<iostream>
#include <iomanip>
using namespace std;
int add(int,int);
double add(double,double);
int _tmain(int argc, _TCHAR* argv[])
{
cout<<add(1,2)<<endl;
cout<<add(1.2,2.2)<<endl;
getchar();
getchar();
return 0;
}
int add(int x,int y)
{
return x+y;
}
double add(double a,double b)
{
return a+b;
}
参数个数上不同的重载函数
该范例定义了3个函数,其函数名都为min,其参数个数分别为2个,3个,4个,其功能分别为取2个,3个,4个整型数据的最小值。
// lianxi.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include<iostream>
#include <iomanip>
using namespace std;
int min(int a,int b);
int min(int a,int b,int c);
int min(int a,int b,int c,int d);
int _tmain(int argc, _TCHAR* argv[])
{
cout<<min(2,3)<<endl;
cout<<min(3,4,5)<<endl;
cout<<min(4,5,6,7)<<endl;
getchar();
getchar();
return 0;
}
int min(int a,int b)
{
return a;
}
int min(int a,int b,int c)
{
int t=min(a,b);
return min(t,c);
}
int min(int a,int b,int c,int d)
{
int t1 = min(a,b);
int t2 = min(c,d);
return min(t1,t2);
}
参考:《21天学通C++》作者:刘蕾