C++學習筆記——第五天 函式
目標
- 掌握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++》作者:劉蕾