小古銀的官方網站(完整教程):http://www.xiaoguyin.com/
C++入門教程視訊:https://www.bilibili.com/vide…
既然用過std::abs()
函式,那麼,現在就以它為例,實現一個myabs()
函式來實現求絕對值。
返回值型別 函式名稱(引數型別 引數名稱, 引數型別 引數名稱)
{
函式的內容
}
基礎示例
根據這個格式實現myabs()
函式:
#include <iostream>
int myabs(int num)
{
int value = 0;
if (num < 0)
{
value = -num;
}
else
{
value = num;
}
return value;
}
int main(void)
{
std::cout << myabs(-1024) << std::endl;
std::cout << myabs(2333) << std::endl;
std::cout << myabs(6666) << std::endl;
return 0;
}
輸出結果:
1024
2333
6666
基礎講解
先看一下呼叫myabs()
的時候跟呼叫std::abs()
函式時是一樣的。
然後再看看定義:
int myabs(int num)
{
int value = 0;
if (num < 0)
{
value = -num;
}
else
{
value = num;
}
return value;
}
myabs
是函式的名稱,myabs
前面是返回值的型別,後面括號內是函式的引數,num
是需要轉成絕對值的值,它只接受int
型別,所以呼叫就可以這樣:
int absnum = myabs(-100);
上面程式碼中,函式引數num
叫做形式引數;而傳進去的引數-100
叫做實際引數。
形式引數實際上是一個區域性變數,它的作用域就是在myabs()
函式內。假設傳入一個數值,上面程式碼函式的形式引數的行為是:int num = 100;
,然後執行函式內的程式碼;假設傳入一個變數value
,那麼形式引數的行為就是:int num = value;
。也就是說,當有引數傳入函式時,傳入引數的行為就是一個賦值行為。所以,如果一個引數佔用記憶體比較大,那就會導致大量資料被複制。
以下程式碼判斷,如果num
小於0就給它一個負號讓它變成正數,然後再賦值給value
;如果num
非負則直接賦值給value
:
int value = 0;
if (num < 0)
{
value = -num;
}
else
{
value = num;
}
然後,myabs()
函式返回計算結果,也就是變數value
:
return value;
當然啦,為了方便分析我做了一些拆分,實際上,myabs()
函式可以簡寫成這樣:
int myabs(int num)
{
if (num < 0)
{
return -num;
}
else
{
return num;
}
}
因為newnum
是int
型別,所以返回值我就決定是int
型別了。如果你覺得返回值肯定是非負的,那麼你也是對的。所以,myabs()
函式也可以寫成這樣:
unsigned int myabs(int num)
{
if (num < 0)
{
return -num;
}
else
{
return num;
}
}
再放一個含有多個引數的函式的栗子:
#include <iostream>
int add(int a, int b)
{
return a + b;
}
int main(void)
{
std::cout << add(-5, 100) << std::endl;
return 0;
}
當然啦,單純地相加就沒必要寫成函式了。
補充知識
在C++11前,為了減少函式返回值的額外開銷,一般將非基本資料型別的型別(例如std::string
)通過引數來返回。C++11開始,返回值直接返回不會帶來額外的開銷。因為返回變數時,編譯器並不會銷燬區域性變數的記憶體而且還會將記憶體地址直接傳遞給儲存返回值的變數。由於這個轉變,使C++設計出來的函式更加直觀地表達出其意義。而這個機制就叫做完美轉發。