- 從零開(kāi)始:Qt可視化程序設(shè)計(jì)基礎(chǔ)教程
- 彭凌西等編著
- 1108字
- 2022-01-06 09:52:50
1.8 參數(shù)和函數(shù)
參數(shù)也叫參變量,它就是一個(gè)變量,傳遞參數(shù)就是傳遞變量。關(guān)于參數(shù),可以這樣去理解:魔法師可以根據(jù)觀眾的要求變出雞、鴨、貓等動(dòng)物,當(dāng)觀眾要求魔法師變出雞時(shí),觀眾說(shuō)出的“雞”對(duì)魔法師而言就是參數(shù)。
函數(shù)是一組一起執(zhí)行一個(gè)任務(wù)的語(yǔ)句。每個(gè)C++程序都至少有一個(gè)函數(shù),即主函數(shù) main(),所有程序都可以定義其他額外的函數(shù)。可以把代碼劃分到不同的函數(shù)中,如何劃分代碼到不同的函數(shù)中可自行決定,但在邏輯上,劃分通常是根據(jù)每個(gè)函數(shù)執(zhí)行一個(gè)特定的任務(wù)進(jìn)行的。函數(shù)的聲明告訴編譯器函數(shù)的名稱、返回類型和參數(shù)。函數(shù)的定義提供了函數(shù)的實(shí)際主體。
· 1.8.1 函數(shù)的定義
函數(shù)的定義一般主要由5個(gè)部分組成:返回值類型、函數(shù)名、參數(shù)列表、函數(shù)體語(yǔ)句、return 表達(dá)式。
具體語(yǔ)法如下。
返回值類型 函數(shù)名 (參數(shù)列表)
{
函數(shù)體語(yǔ)句
return表達(dá)式
}
● 返回值類型 :一個(gè)函數(shù)可以返回一個(gè)值,有些函數(shù)只是執(zhí)行所需的操作而不返回值,在這種情況下,返回值類型是void。
● 函數(shù)名:這是函數(shù)的實(shí)際名稱,自定義函數(shù)名須滿足變量名命名規(guī)范。
● 參數(shù)列表:使用該函數(shù)時(shí)傳入的數(shù)據(jù)。
● 函數(shù)體語(yǔ)句:“{}”內(nèi)的代碼,函數(shù)內(nèi)需要執(zhí)行的語(yǔ)句。
● return表達(dá)式:和返回值類型有關(guān),函數(shù)執(zhí)行完后,返回相應(yīng)的數(shù)據(jù)。
具體定義方法見(jiàn)例1-29。
例1-29:定義一個(gè)加法函數(shù),實(shí)現(xiàn)兩個(gè)數(shù)相加。
//函數(shù)定義
#include <iostream>
using namespace std;
int add(int num1, int num2)//包括了2個(gè)形式參數(shù)(簡(jiǎn)稱形參)
{
int sum = num1 + num2;
return sum;//函數(shù)返回值
}
· 1.8.2 函數(shù)調(diào)用
功能:創(chuàng)建C++函數(shù)時(shí),會(huì)定義函數(shù)的任務(wù),然后通過(guò)調(diào)用函數(shù)來(lái)完成已定義的任務(wù)。當(dāng)程序調(diào)用函數(shù)時(shí),程序控制權(quán)會(huì)被轉(zhuǎn)移給被調(diào)用的函數(shù)。被調(diào)用的函數(shù)執(zhí)行已定義的任務(wù),當(dāng)函數(shù)的返回語(yǔ)句被執(zhí)行時(shí),或到達(dá)函數(shù)的結(jié)束標(biāo)記花括號(hào)位置時(shí),會(huì)把程序控制權(quán)交還給主程序。調(diào)用函數(shù)時(shí),傳遞所需參數(shù),如果函數(shù)返回一個(gè)值,則可以存儲(chǔ)該返回值。
語(yǔ)法:函數(shù)名(參數(shù))。
具體調(diào)用方法見(jiàn)例1-30。
例1-30:函數(shù)調(diào)用。
#include<iostream>
using namespace std;
//函數(shù)定義
int add(int num1, int num2) //定義中的num1、num2稱為形式參數(shù),簡(jiǎn)稱形參
{
int sum = num1 + num2;
return sum;
}
int main() {
int a = 10;
int b = 10;
//調(diào)用add()函數(shù)
int sum = add(a, b);//調(diào)用時(shí)的a、b稱為實(shí)際參數(shù),簡(jiǎn)稱實(shí)參
cout << "sum = " << sum << endl;
a = 100;
b = 100;
sum = add(a, b);
cout << "sum = " << sum << endl;
return 0;
}
例1-30運(yùn)行結(jié)果如圖1-49所示。
圖1-49 例1-30運(yùn)行結(jié)果
總結(jié):函數(shù)定義里圓括號(hào)內(nèi)的參數(shù)稱為形式參數(shù)(簡(jiǎn)稱形參),函數(shù)調(diào)用時(shí)傳入的參數(shù)稱為實(shí)際參數(shù)(簡(jiǎn)稱實(shí)參)。
· 1.8.3 值傳遞
C語(yǔ)言的參數(shù)傳遞方法有3種:值傳遞、地址傳遞、引用傳遞,具體如下。
值傳遞:在函數(shù)調(diào)用時(shí),實(shí)參以數(shù)值形式傳給形參。在進(jìn)行值傳遞時(shí),如果形參發(fā)生改變,并不會(huì)影響實(shí)參。
地址傳遞:在調(diào)用函數(shù)的時(shí)候,將參數(shù)的值所在的地址復(fù)制一份過(guò)去。因此,被調(diào)用函數(shù)對(duì)參數(shù)地址的值進(jìn)行修改會(huì)影響原來(lái)的值。
地址傳遞是比較難理解的概念,對(duì)此進(jìn)行對(duì)比說(shuō)明:關(guān)于值傳遞,可這樣去理解,子函數(shù)以形參形式從主函數(shù)中傳入數(shù)據(jù),但這個(gè)數(shù)據(jù)只和形參發(fā)生傳值后就立刻返回,而后子函數(shù)發(fā)生的數(shù)據(jù)變化不會(huì)影響主函數(shù)的數(shù)據(jù);關(guān)于地址傳遞,子函數(shù)以形參形式從主函數(shù)中傳入的是存放數(shù)據(jù)的地址,因此子函數(shù)的數(shù)據(jù)變化就是主函數(shù)的數(shù)據(jù)變化。
進(jìn)一步通過(guò)“孫悟空”和“楊戩”來(lái)舉例說(shuō)明。定義孫悟空為一個(gè)變量,楊戩為一個(gè)函數(shù),變量孫悟空可利用分身術(shù)產(chǎn)生一個(gè)形參傳遞給函數(shù)楊戩,這時(shí)候?yàn)橹祩鬟f。函數(shù)楊戩怎樣收拾變量孫悟空的分身(形參,只傳遞值的副本)都不會(huì)對(duì)變量孫悟空本身產(chǎn)生影響,但如果變量孫悟空把真身的地址告訴了函數(shù)楊戩(地址傳遞,傳遞變量孫悟空在內(nèi)存中的地址),函數(shù)楊戩就可以根據(jù)地址找到變量孫悟空本身,這時(shí)候函數(shù)楊戩對(duì)變量孫悟空的操作就會(huì)改變孫悟空的值了。
引用傳遞:引用是變量的一個(gè)別名,調(diào)用別名和調(diào)用變量是完全一樣的,其效果和地址傳遞一樣。
這里先對(duì)值傳遞進(jìn)行舉例解釋,見(jiàn)例1-31。地址傳遞舉例請(qǐng)見(jiàn)1.10.4小節(jié),引用傳遞舉例請(qǐng)見(jiàn)2.2.2小節(jié)。
例1-31:值傳遞。
#include<iostream>
using namespace std;
void swap1(int num1, int num2)//num1和numb2為形參
{
cout<<"swap1中參數(shù)交換前: num1= " << num1 <<" num2 ="<<num2<< endl;
int temp = num1;
num1 = num2;
num2 = temp;
cout<<"swap1中參數(shù)交換后: num1= " << num1 <<" num2 ="<<num2<< endl;
return ; //當(dāng)函數(shù)聲明時(shí),如果函數(shù)返回類型為void,則該函數(shù)不需要返回值,此處可不寫(xiě)return
}
int main() {
int a = 10;
int b = 20;
swap1(a, b);//調(diào)用函數(shù)swap(), a和b為實(shí)參
cout << "調(diào)用swap1交換后main中的 a= " << a<<" b="<< b<< endl;
return 0;
}
例1-31運(yùn)行結(jié)果如圖1-50所示。
圖1-50 例1-31運(yùn)行結(jié)果
總結(jié):在進(jìn)行值傳遞時(shí),形參是改變不了實(shí)參(傳遞前的變量原值)的。
· 1.8.4 函數(shù)的常見(jiàn)樣式
常見(jiàn)的函數(shù)樣式有以下4種。
● 無(wú)參(數(shù))無(wú)返(回值)。
● 有參無(wú)返。
● 無(wú)參有返。
● 有參有返。
具體見(jiàn)例1-32。
例1-32:函數(shù)常見(jiàn)樣式。
#include<iostream>
using namespace std;
//函數(shù)常見(jiàn)樣式
//1.無(wú)參無(wú)返
void test01()
{
void a = 10; //無(wú)類型不可以創(chuàng)建變量,原因是它無(wú)法分配內(nèi)存
cout << "this is test01" << endl;
test01();//函數(shù)調(diào)用
}
//2.有參無(wú)返
void test02(int a)
{
cout << "this is test02" << endl;
cout << "a = " << a << endl;
}
//3.無(wú)參有返
int test03()
{
cout << "this is test03 " << endl;
return 10;
}
//4.有參有返
int test04(int a, int b)
{
cout << "this is test04 " << endl;
int sum = a + b;
return sum;
}
· 1.8.5 函數(shù)的聲明
作用:告訴編譯器函數(shù)名稱和如何調(diào)用函數(shù)。函數(shù)的實(shí)際主體可以單獨(dú)定義。
函數(shù)可以聲明多次,但是函數(shù)只能定義一次。
在函數(shù)的聲明中,參數(shù)的名稱并不重要,只有參數(shù)的類型是必需的,因此下面也是有效的聲明。
int max(int, int);
具體聲明方法見(jiàn)例1-33。
例1-33:函數(shù)的聲明。
#include<iostream>
using namespace std;
//聲明可以多次,定義只能一次
int max(int a, int b);
int max(int a, int b);
int main() {
int a = 100;
int b = 200;
cout << max(a, b) << endl;
return 0;
}
//定義
int max(int a, int b)
{
return a > b ? a : b;
}
例1-33運(yùn)行結(jié)果如圖1-51所示。
圖1-51 例1-33運(yùn)行結(jié)果
· 1.8.6 外部文件
作用:調(diào)用外部文件可以讓代碼結(jié)構(gòu)更加清晰,也就是所謂的用分文件保存源文件代碼。
函數(shù)分文件編寫(xiě)一般有4個(gè)步驟。
● 創(chuàng)建擴(kuò)展名為.h的頭文件。
● 創(chuàng)建擴(kuò)展名為.cpp的源文件。
● 在頭文件中寫(xiě)函數(shù)的聲明。
● 在源文件中寫(xiě)函數(shù)的定義。
具體使用方法見(jiàn)例1-34。
例1-34:外部文件。
//swap.h文件
#include<iostream>
using namespace std;
//實(shí)現(xiàn)兩個(gè)數(shù)字交換的函數(shù)聲明
void swap(int a, int b);
//swap.cpp文件
#include "swap.h"
void swap(int a, int b)
{
int temp = a;
a = b;
b = temp;
cout << "a = " << a << endl;
cout << "b = " << b << endl;
}
//main()函數(shù)文件
#include "swap.h"
int main() {
int a = 100;
int b = 200;
swap(a, b);
return 0;
}
- Unity 2020 By Example
- 程序員數(shù)學(xué):用Python學(xué)透線性代數(shù)和微積分
- Xcode 7 Essentials(Second Edition)
- Web開(kāi)發(fā)的貴族:ASP.NET 3.5+SQL Server 2008
- 自然語(yǔ)言處理Python進(jìn)階
- VMware虛擬化技術(shù)
- C/C++程序員面試指南
- Extending Unity with Editor Scripting
- NGUI for Unity
- Software-Defined Networking with OpenFlow(Second Edition)
- SQL Server實(shí)例教程(2008版)
- Learning Shiny
- Mastering Clojure
- Leaflet.js Essentials
- 打造流暢的Android App