您好,登錄后才能下訂單哦!
這篇文章給大家分享的是有關C++中函數怎么用的內容。小編覺得挺實用的,因此分享給大家做個參考,一起跟隨小編過來看看吧。
第六章 函數
函數是一個命名了的代碼塊,通過調用函數執行相應的代碼。
通過調用運算符(call operator)來執行函數。其形式是一對圓括號。
函數的調用完成兩項工作(如下),此時主調函數(calling function)的執行被暫時中斷,被調函數(called function)開始執行。
用實參初始化函數對應的形參。
將控制權轉移給被調函數。
return語句:
返回return語句中的值
將控制權從被調函數移回主調函數
名字有作用域,對象有生命周期(lifetime)
自動對象(automatic object):當函數的控制路徑經過變量定義語句時創建該對象,當達到定義所在的塊末尾時銷毀它。
局部靜態對象:程序執行路徑第一次經過對象定義語句時初始化,知道程序終止才被銷毀。
將局部變量定義為static獲得,例如:
//統計函數count_calls ()被調用了多少次
size_t count_calls ()
{
static size_t ctr = 0; //調用結束后,這個值仍然有效
return ++ctr;
}
int main()
{
for (size_t i = 0; i != 10; ++i)
cout << cout_calls() << endl;
return 0;
}
也稱作函數原型(function prototype)
函數三要素(返回類型、函數名、形參類型)描述了函數的接口,函數聲明中形參名可省略。
函數應在頭文件中聲明,源文件中定義。
分離式編譯
如果形參是引用類型,它將綁定到對應的實參上;否則,將實參的值拷貝后賦給形參。
- 如果無需修改引用形參的值,最好將其聲明為常量引用。
假設main函數位于可執行文件prog內,我們可以向程序傳遞下面的選項:
prog -d -o ofile data0
這些命令通過兩個可選的形參傳遞給main函數:
int main(int argc, char *argv[]) {...} //或: int main(int argc, char **argv) {...}
當實參傳給main函數之后,argv的第一個元素指向程序的名字或者一個空字符串,接下來的元素一次傳遞命令行提供的實參。最后一個指針只會掉元素值保證為0。
- 以上面的命令行為例:
argc = 5;argv[0] = "prog";argv[1] = "-d";argv[2] = "-o";argv[3] = "ofile";argv[4] = "data0";argv[5] = 0;
C++11新標準提供兩種方法編寫能處理不同數量實參的函數:
所有實參類型相同,可以傳遞一個名為initializer_list的標準庫類型。
實參類型不同,我們可以編寫一種特殊的函數,叫做可變參數模板。
C++還有一種特殊的形參類型:省略符。可以用它傳遞可變數量的實參。這種功能一般只用于與C函數交互的接口程序。
initializer_list形參
其類型定義在同名的頭文件中
提供如下操作:
initializer_list<T> lst; //默認初始化,T類型元素的空列表
initializer_list<T> lst{a,b,c...};
//lst的元素數量和初始值一樣多;lst的元素是對應初始值的副本;列表中的元素是const
lst2(lst)
lst2 = lst //拷貝或復制一個initializer_list對象不會拷貝列表中的元素;拷貝后,原始列表和副本元素共享
lst.size() //列表中元素的數量
lst.begin() //返回指向lst中首元素的指針
lst.end() //返回指向lst中尾元素下一位置的指針
引用返回左值,其他返回類型得到右值。
列表初始化返回值:C++11新標準規定,函數可以返回花括號包圍的值的列表。
允許main函數沒有返回值(若沒有,編譯器隱式地插入return 0)
返回0表示執行成功,其他值依機器而定。
為了使返回值與機器無關,cstdlib頭文件定義了兩個預處理變量,分別表示成功和失敗:
return EXIT_FAILURE;
return EXIT_SUCCESS;
//因為它們是預處理變量,所以既不能在前面加上std::,也不能在using聲明里出現。
使用類型別名
typedef int arrT[10]; //arrT是一個類型別名,它表示的類型是含有10個整數的數組
using arrT = int[10]; //與上一句等價
arrT* func(int i); //func返回一個指向含有10個整數的數組的指針
聲明一個返回數組指針的函數,形式如下
Type (*function(parameter_list)) [dimension]
//Type表示返回的數組指針指向的數組元素類型
//dimension表示數組的大小
//例如:
int (*func(int i)) [10];
使用尾置返回類型(C++11)
auto func(int i) -> int(*)[10];
使用decltype
int odd[] = {1,3,5,7,9};
int even[] = {0,2,4,6,8};
decltype(odd) *arrPtr(int i)
{
return (i % 2) ? &odd : &even; //返回一個指向數組的指針
}
如果同一作用域內的幾個函數名字相同但形參列表不同,我們稱之為重載(overloaded)函數。
不允許兩個函數除了返回類型外其他所有要素都相同。
重載與作用域:一旦在當前作用域中找到了所需的名字,編譯器就會忽略掉外層作用域中的同名實體。
介紹三種函數相關的語言特性:默認實參、內聯函數、constexpr函數。
調用包含默認實參的函數時,可以包含該實參,也可以省略該實參。
一旦某個形參被賦予了默認值,它后面所有的形參都必須有默認值。
調用函數一般比求等價表達式的值要慢,內聯函數可避免函數調用的開銷。
- 將函數指定為內聯函數,通常就是將它在每個調用點上“內聯地”展開。
函數的返回類型和所有的形參類型都得是字面值類型。
函數中必須有且只有一條return語句。
constexpr函數被隱式地指定為內聯函數。
程序可以包含一些用于調試的代碼,但這些代碼只在開發程序時使用。當應用程序編寫完成準備發布時,要先屏蔽掉調試代碼。這種方法用到兩項預處理功能:assert和NDEBUG。
#include <cassert>assert(expr);//首先對expr求值,//如果表達式為假(即0),assert輸出信息并終止程序的執行。//如果表達式為真(即非0),assert什么也不做。//例如:對一個文本進行操作的程序可能要求所給定單詞的長度都大于某個閾值。assert(word.size() > threshold;
assert的行為依賴于一個名為NDEBUG的預處理變量的狀態。如果定義了NDEBUG,則assert什么也不做。默認狀態下沒有定義NDEBUG,此時assert將運行執行時檢查。
使用#define語句定義NDEBUG,從而關閉調試狀態。
很多編譯器都提供了命令行選項使我們可以定義預處理變量。
$ CC -D NDEBUG main.C #微軟編譯器中用 /D
這只是調試程序的輔助手段,不能代替真正的邏輯檢查,也不能代替程序本應該包含的錯誤檢查。
除了assert以外,也能使用NDEBUG編寫自己的條件調試代碼:
//如果定義了NDEBUG,#ifndef和#endif之間的代碼將被忽略void print(const int ia[], aize_t size) { #ifndef NDEBUG //_ _func_ _是編譯器定義的一個局部靜態變量,用于存放函數的名字,它是const char的一個靜態數組。 cerr << _ _func_ _ << "array size is " << size << endl; #endif}
除了_ _ func _ _之外,還有其它四個名字:
_ _FILE_ _ 存放文件名的字符串字面值 _ _LINE_ _ 存放當前行號的整型字面值 _ _TIME_ _ 存放文件編譯時間的字符串字面值 _ _DATA_ _ 存放文件編譯日期的字符串字面值
bool lengthCompare(const string &, const string &);//pf指向一個函數,該函數的參數是兩個const string的引用,返回值是bool類型。注意圓括號必不可少bool (*pf) (const string &, const string &); //未初始化
當我們把函數名作為值使用時,該函數自動地轉換成指針
pf = lengthCompare; //pf指向名為lengthCompare的函數pf = &lengthCompare; //等價賦值語句,&是可選的
調用該函數:
//此三個調用等價bool b1 = pf("hello", "goodbye");bool b2 = (*pf)("hello", "goodbye");bool b3 = lengthCompare("hello", "goodbye");
感謝各位的閱讀!關于“C++中函數怎么用”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,讓大家可以學到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。