目錄
函數基礎
局部物件
返回数组指针
函数重载
特殊用途语言特性
默认实参
内联函数(inline)
constexpr函数
内联函数和constexpr函数通常定义在头文件中
调试帮助
assert预处理宏
NDEBUG预处理变量
函数指针
首頁 後端開發 C#.Net教程 第六章C++:函數基礎與應用

第六章C++:函數基礎與應用

Aug 06, 2018 am 10:47 AM
c++

第六章 函數

函數是一個被命名了的程式碼區塊,透過呼叫函數執行對應的程式碼。

函數基礎

  • 透過呼叫運算子(call operator)來執行函數。其形式為一對圓括號。

  • 函數的呼叫完成兩項工作(如下),此時主調函數(calling function)的執行被暫時中斷,被調函數(called function )開始執行。

    • 用實參初始化函數對應的形參。

    • 將控制權轉移給被調函數。

  • return語句:

    • #傳回return語句中的值

    • 將控制權從被調函數移回主調函數

局部物件

  • ##名字有作用域,物件有

    生命週期(lifetime)

  • 自動物件(automatic object):當函數的控制路徑經過變數定義語句時建立該對象,當達到定義所在的區塊末尾時銷毀它。

  • 局部靜態物件:程式執行路徑第一次經過物件定義語句時初始化,知道程式終止才被銷毀。

    • 將局部變數定義為

      static 取得,例如:
      //統計函數count_calls ()被呼叫了多少次<br>size_t count_calls () <br>{ <br>static size_t ctr = 0;  //呼叫結束後,這個值仍然有效<br>return ctr; <br>} <br>int main () <br>{ <br>for (size_t i = 0; i != 10; i) <br>cout << cout_calls() << endl; <br>return 0; <br>} <br><br>

函數宣告

  • #也稱為

    函數原型(function prototype)

  • 函數三要素(

    返回類型、函數名稱、形參型別)描述了函數的接口,函數宣告中形參名可省略。

  • 函數應在頭檔中聲明,原始檔中定義。

  • 分離式編譯

參數傳遞

#如果形參是參考類型,它將綁定到對應的實參上;否則,將實參的值拷貝後賦給形參。

- 如果無需修改引用形參的值,最好將其宣告為常數引用。

main:處理命令列選項

假設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新標準提供兩種方法編寫能處理不同數量實參的函數:


    1. 所有實參類型相同,可以傳遞一個名為initializer_list的標準函式庫類型。

    2. 實參類型不同,我們可以寫一個特殊的函數,叫做可變參數模板。

  • C 還有一種特殊的形參類型:省略符。可以用它傳遞可變數量的實參。這種功能一般只用於與C函數互動的介面程式。

  • initializer_list形參考

    • #其型別定義在同名的頭檔中

    • 提供以下操作:


      initializer_list<T> lst;    //預設初始化,T型別元素的空白列表<br/>initializer_list<T> lst{a ,b,c...}; <br/>//lst的元素數量和初始值一樣多;lst的元素是對應初始值的副本;列表中的元素是const <br/>lst2(lst) <br/> lst2 = lst  //拷貝或複製一個initializer_list物件不會拷貝清單中的元素;拷貝後,原始清單和副本元素共享<br/>lst.size()  //清單中元素的數量<br/>lst.begin( ) //傳回指向lst中首元素的指標<br/>lst.end()   //傳回指向lst中尾元素下一位置的指標<br/><br/>

傳回型別與return語句

  • 引用傳回左值,其他回傳型別得到右值。

  • 列表初始化傳回值:C 11新標準規定,函數可以傳回花括號包圍的值的清單。

主函數main的回傳值

  • 允許main函數沒有回傳值(若沒有,編譯器隱含地插入return 0)

  • 返回0表示执行成功,其他值依机器而定。

  • 为了使返回值与机器无关,cstdlib头文件定义了两个预处理变量,分别表示成功和失败:
    <br/>return EXIT_FAILURE; <br/>return EXIT_SUCCESS; <br/>//因为它们是预处理变量,所以既不能在前面加上std::,也不能在using声明里出现。 <br/>

返回数组指针

  1. 使用类型别名
    <br/>typedef int arrT[10]; //arrT是一个类型别名,它表示的类型是含有10个整数的数组 <br/>using arrT = int[10]; //与上一句等价 <br/>arrT* func(int i); //func返回一个指向含有10个整数的数组的指针 <br/>

  2. 声明一个返回数组指针的函数,形式如下
    <br/>Type (*function(parameter_list)) [dimension] <br/>//Type表示返回的数组指针指向的数组元素类型 <br/>//dimension表示数组的大小 <br/>//例如: <br/>int (*func(int i)) [10]; <br/>

  3. 使用尾置返回类型(C++11)
    <br/>auto func(int i) -> int(*)[10]; <br/>

  4. 使用decltype
    <br/>int odd[] = {1,3,5,7,9}; <br/>int even[] = {0,2,4,6,8}; <br/>decltype(odd) *arrPtr(int i) <br/>{ <br/> return (i % 2) ? &odd : &even; //返回一个指向数组的指针 <br/>} <br/>

函数重载

如果同一作用域内的几个函数名字相同但形参列表不同,我们称之为重载(overloaded)函数

  • 不允许两个函数除了返回类型外其他所有要素都相同。

  • 重载与作用域:一旦在当前作用域中找到了所需的名字,编译器就会忽略掉外层作用域中的同名实体。

特殊用途语言特性

介绍三种函数相关的语言特性:默认实参、内联函数、constexpr函数。

默认实参

  • 调用包含默认实参的函数时,可以包含该实参,也可以省略该实参。

  • 一旦某个形参被赋予了默认值,它后面所有的形参都必须有默认值。

内联函数(inline)

调用函数一般比求等价表达式的值要慢,内联函数可避免函数调用的开销。
- 将函数指定为内联函数,通常就是将它在每个调用点上“内联地”展开。

constexpr函数

  • 函数的返回类型和所有的形参类型都得是字面值类型。

  • 函数中必须有且只有一条return语句。

  • constexpr函数被隐式地指定为内联函数。

内联函数和constexpr函数通常定义在头文件中

调试帮助

程序可以包含一些用于调试的代码,但这些代码只在开发程序时使用。当应用程序编写完成准备发布时,要先屏蔽掉调试代码。这种方法用到两项预处理功能:assert和NDEBUG。

assert预处理宏

#include <cassert>assert(expr);//首先对expr求值,//如果表达式为假(即0),assert输出信息并终止程序的执行。//如果表达式为真(即非0),assert什么也不做。//例如:对一个文本进行操作的程序可能要求所给定单词的长度都大于某个阈值。assert(word.size() > threshold;
登入後複製

NDEBUG预处理变量

  • assert的行为依赖于一个名为NDEBUG的预处理变量的状态。如果定义了NDEBUG,则assert什么也不做。默认状态下没有定义NDEBUG,此时assert将运行执行时检查。

    • 使用#define语句定义NDEBUG,从而关闭调试状态。

    • 很多编译器都提供了命令行选项使我们可以定义预处理变量。
      <br/>$ CC -D NDEBUG main.C #微软编译器中用 /D <br/>

  • 这只是调试程序的辅助手段,不能代替真正的逻辑检查,也不能代替程序本应该包含的错误检查。

  • 除了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++Primer第五版

相关文章:

第四章C++:表达式概念-运算符的应用

第五章C :語句的相關介紹

以上是第六章C++:函數基礎與應用的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

<🎜>:泡泡膠模擬器無窮大 - 如何獲取和使用皇家鑰匙
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
北端:融合系統,解釋
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
Mandragora:巫婆樹的耳語 - 如何解鎖抓鉤
3 週前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

熱門話題

Java教學
1664
14
CakePHP 教程
1423
52
Laravel 教程
1321
25
PHP教程
1269
29
C# 教程
1249
24
C#與C:歷史,進化和未來前景 C#與C:歷史,進化和未來前景 Apr 19, 2025 am 12:07 AM

C#和C 的歷史與演變各有特色,未來前景也不同。 1.C 由BjarneStroustrup在1983年發明,旨在將面向對象編程引入C語言,其演變歷程包括多次標準化,如C 11引入auto關鍵字和lambda表達式,C 20引入概念和協程,未來將專注於性能和系統級編程。 2.C#由微軟在2000年發布,結合C 和Java的優點,其演變注重簡潔性和生產力,如C#2.0引入泛型,C#5.0引入異步編程,未來將專注於開發者的生產力和雲計算。

vscode在哪寫代碼 vscode在哪寫代碼 Apr 15, 2025 pm 09:54 PM

在 Visual Studio Code(VSCode)中編寫代碼簡單易行,只需安裝 VSCode、創建項目、選擇語言、創建文件、編寫代碼、保存並運行即可。 VSCode 的優點包括跨平台、免費開源、強大功能、擴展豐富,以及輕量快速。

Golang和C:並發與原始速度 Golang和C:並發與原始速度 Apr 21, 2025 am 12:16 AM

Golang在並發性上優於C ,而C 在原始速度上優於Golang。 1)Golang通過goroutine和channel實現高效並發,適合處理大量並發任務。 2)C 通過編譯器優化和標準庫,提供接近硬件的高性能,適合需要極致優化的應用。

Python與C:學習曲線和易用性 Python與C:學習曲線和易用性 Apr 19, 2025 am 12:20 AM

Python更易學且易用,C 則更強大但複雜。 1.Python語法簡潔,適合初學者,動態類型和自動內存管理使其易用,但可能導致運行時錯誤。 2.C 提供低級控制和高級特性,適合高性能應用,但學習門檻高,需手動管理內存和類型安全。

Golang vs.C:性能和速度比較 Golang vs.C:性能和速度比較 Apr 21, 2025 am 12:13 AM

Golang適合快速開發和並發場景,C 適用於需要極致性能和低級控制的場景。 1)Golang通過垃圾回收和並發機制提升性能,適合高並發Web服務開發。 2)C 通過手動內存管理和編譯器優化達到極致性能,適用於嵌入式系統開發。

Golang和C:性能的權衡 Golang和C:性能的權衡 Apr 17, 2025 am 12:18 AM

Golang和C 在性能上的差異主要體現在內存管理、編譯優化和運行時效率等方面。 1)Golang的垃圾回收機制方便但可能影響性能,2)C 的手動內存管理和編譯器優化在遞歸計算中表現更為高效。

表演競賽:Golang vs.C 表演競賽:Golang vs.C Apr 16, 2025 am 12:07 AM

Golang和C 在性能競賽中的表現各有優勢:1)Golang適合高並發和快速開發,2)C 提供更高性能和細粒度控制。選擇應基於項目需求和團隊技術棧。

vscode如何執行代碼 vscode如何執行代碼 Apr 15, 2025 pm 09:51 PM

在 VS Code 中執行代碼只需六個步驟:1. 打開項目;2. 創建和編寫代碼文件;3. 打開終端;4. 導航到項目目錄;5. 使用適當的命令執行代碼;6. 查看輸出。

See all articles