第 6 章 C++: 関数の基本と応用

php是最好的语言
php是最好的语言オリジナル
2018-08-06 10:47:131504ブラウズ

第 6 章 関数

関数は、関数を呼び出すことによって対応するコードを実行する、名前付きのコード ブロックです。

関数の基本

  • 関数は call 演算子 (call 演算子) で実行します。その形式は一対の括弧です。

  • 関数の呼び出しにより、次の 2 つのタスクが完了します。このとき、メイン呼び出し関数 (呼び出し関数) の実行は一時的に中断されます。および呼び出された関数 (呼び出された関数) の実行を開始します。

    • #関数に対応する仮パラメータを実パラメータで初期化します。

    • 呼び出された関数に制御を移します。

  • return ステートメント:

    • return ステートメントで値を返す

    • 呼び出した関数から呼び出した関数に制御を戻す

ローカル オブジェクト

  • 名前にはスコープがあり、オブジェクトには

    Lifecycle(ライフタイム)

  • 自動オブジェクト(自動オブジェクト): このオブジェクトは、関数の制御パスが変数定義ステートメントを通過するときに作成されます。 . それが定義されているブロックの終わりに達したら、それを破棄します。

  • ローカル静的オブジェクト: プログラムの実行パスが初めてオブジェクト定義ステートメントを通過するときに初期化され、プログラムが終了するまで破棄されません。

    • ローカル変数を

      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 e54720ff7629d1e7b23cf5fbd4a55e60 lst; //デフォルトの初期化、T 型要素の空のリスト <p>initializer_list85dd6df6fa93d8513a0024c700b1f123 int(*)[10]; <br></p>

    • 使用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++:表达式概念-运算符的应用

      第 5C 章: ステートメントの概要

以上が第 6 章 C++: 関数の基本と応用の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。