1.4関数初見——入門

22411 ワード

from http://www.learncpp.com/cpp-tutorial/14-a-first-look-at-functions/
一つの関数は、多くの語句の順序を組み合わせて、一つの特殊な機能を完成させます.各プログラムには入口関数が必要です.しかし、ほとんどのプログラムにはより多くの関数が含まれています.それらの働き方はメールと似ています.
通常、あなたのプログラムは実行中のステートメントを中断して、他のいくつかのことを処理する必要があります.現実的な生活の中で、よくこのようにします.例えば、電話が必要なことを思い出したら、本を読んでいるかもしれません.ブックマークを置いて電話してください.電話してから本を読み続けてください.
C++プログラムの働き方はこのような過程に似ています.一つのプログラムが関数によって呼び出されると、関数のステートメントが順次実行されます.関数コールとは、CPU端末に現在の関数を教え、他の関数を実行することです.CPUは、現在の実行ポイントにブックマークを置き、呼び出し関数のステートメントを実行します.この関数の実行が完了すると、CPUはブックマークを元の場所に戻して実行を再開します.
ここに新しい関数宣言と呼び出しの例があります.
   1: //#include <stdafx.h> // Visual Studio users need to uncomment this line
   2: #include <iostream>
   3:  
   4: // Declaration of function DoPrint()
   5: void DoPrint()
   6: {
   7:     using namespace std;  // we need this in each function that uses cout and endl
   8:     cout << "In DoPrint()" << endl;
   9: }
  10:  
  11: // Declaration of main()
  12: int main()
  13: {
  14:     using namespace std;  // we need this in each function that uses cout and endl
  15:     cout << "Starting main()" << endl;
  16:     DoPrint(); // This is a function call to DoPrint()
  17:     cout << "Ending main()" << endl;
  18:     return 0;
  19: }
 
このプログラムは下記の出力を発生します.
Starting main()
In DoPrint()
Ending main()
 
このプログラムは、main()関数の先頭から実行し、1行目はStarting main()を印刷します.2行目はDoPrint関数を呼び出します.この時点では、main関数の実行文が中断され、CPUがDoPrint()関数に落ちます.DoPrint関数の1行目は、In DoPrint()を出力します.DoPrint関数が実行されると、main関数は再開されます.したがって、電子メール関数の次のステートメントは、出力Ending main()を実行します.
関数は複数回呼び出すことができます.
   1: //#include <stdafx.h> // Visual Studio users need to uncomment this line
   2: #include <iostream>
   3:  
   4: // Declaration of function DoPrint()
   5: void DoPrint()
   6: {
   7:     using namespace std;
   8:     cout << "In DoPrint()" << endl;
   9: }
  10:  
  11: // Declaration of main()
  12: int main()
  13: {
  14:     using namespace std;
  15:     cout << "Starting main()" << endl;
  16:     DoPrint(); // This is a function call to DoPrint()
  17:     DoPrint(); // This is a function call to DoPrint()
  18:     DoPrint(); // This is a function call to DoPrint()
  19:     cout << "Ending main()" << endl;
  20:     return 0;
  21: }
 
関数は次のような結果を生成します.
Starting main()

In DoPrint()

In DoPrint()

In DoPrint()

Ending main()
この例では関数mainは3回中断された.
main関数は他の関数を呼び出すための唯一の機能ではありません.以下の例では、DoPrint()関数は第二の関数、DoPrint 2()を呼び出します.
   1: //#include <stdafx.h> // Visual Studio users need to uncomment this line
   2: #include <iostream>
   3:  
   4: void DoPrint2()
   5: {
   6:     using namespace std;
   7:     cout << "In DoPrint2()" << endl;
   8: }
   9:  
  10: // Declaration of function DoPrint()
  11: void DoPrint()
  12: {
  13:     using namespace std;
  14:     cout << "Starting DoPrint()" << endl;
  15:     DoPrint2(); // This is a function call to DoPrint2()
  16:     DoPrint2(); // This is a function call to DoPrint2()
  17:     cout << "Ending DoPrint()" << endl;
  18: }
  19:  
  20: // Declaration of main()
  21: int main()
  22: {
  23:     using namespace std;
  24:     cout << "Starting main()" << endl;
  25:     DoPrint(); // This is a function call to DoPrint()
  26:     cout << "Ending main()" << endl;
  27:     return 0;
  28: }
 
発生した出力は以下の通りです.
Starting main()

Starting DoPrint()

In DoPrint2()

In DoPrint2()

Ending DoPrint()

Ending main()
 
戻り値
覚えているなら、メール関数の実行が完了したら、return文を使ってオペレーティングシステムに値を返します.あなたが書いた関数は数値を返してもいいです.関数宣言で関数の戻りのタイプを変えることで実現した.戻るタイプがvoidであるということは、関数が1つの値を返す必要がないということを意味します.戻るタイプはintで、関数が整数型の調合者に戻ることを意味します.
   1: // void means the function does not return a value to the caller
   2: void ReturnNothing()
   3: {
   4:     // This function does not return a value
   5: }
   6:  
   7: // int means the function returns an integer value to the caller
   8: int Return5()
   9: {
  10:     return 5;
  11: }
 
これらの関数をプログラムで使いましょう.
   1: cout << Return5(); // prints 5
   2: cout << Return5() + 2; // prints 7
   3: cout << ReturnNothing(); // This will not compile
 
最初のステートメントでは、Return 5が実行され、関数は5に戻り、この値が出力されます.
第二の文では、Return 5が実行され、関数は5を使用者に返します.式5+2は7を生成する.7はcoutに伝わっています
第三の文では、ReturnNothing()はvoidに戻る.voidをcoutに送るのは無理です.コンパイラはこの行をコンパイルするとエラーが発生します.
一つの通常の質問は、「私の関数はリセット文で複数の値を返してもいいですか?」という答えではありません.関数はreturn文で一つの値しか返しません.しかし、この問題を解決する方法があります.関数を深く理解する章で議論します.
 
main関数に戻ります
今は、メーン関数がどのように実行されるかの基本概念を理解しました.一つのプログラムが実行されると、オペレーティングシステムはメール関数の呼び出しを生成する.メール関数の先頭に移動します.main関数のステートメントは順次実行されます.最後に、main関数はオペレーティングシステムに整数値を返します.これはmain関数宣言がint main()の原因です.
いくつかのコンパイラはvoid main()の声明に対してエラーメッセージを与えません.技術的には無理です.コンパイラがvoid main()関数を見たとき、これは次のように解釈される.
   1: int main()
   2: {
   3:     // your code here
   4:     return 0;
   5: }
メール関数をint型として宣言します.値を返すときは0です.
 
パラメータ
戻り値の部分では、関数が調整者に値を返すことができることが分かります.パラメータは、使用者が関数に情報を伝えることを許可するものです.これは、書き上げられた関数が一般化されたタスクを完了することができます.使用する特殊な値を心配することなく、確実な変数の値を呼び出しに渡すことができます.
例を通してよく理解できます.ここには簡単な例があります.二つのパラメータを加算して、戻りと:
   1: //#include <stdafx.h> // Visual Studio users need to uncomment this line
   2: #include <iostream>
   3:  
   4: // add takes two integers as parameters, and returns the result of their sum
   5: // add does not care what the exact values of x and y are
   6: int add(int x, int y)
   7: {
   8:     return x + y;
   9: }
  10:  
  11: int main()
  12: {
  13:     using namespace std;
  14:     // It is the caller of add() that decides the exact values of x and y
  15:     cout << add(4, 5) << endl; // x=4 and y=5 are the parameters
  16:     return 0;
  17: }
add関数が呼び出されると、xは4に割り当てられ、yは5に割り当てられます.関数はx+yを実行します.結果は9で、この値をコーディネーターに返します.そして9をcoutに送り、スクリーンに出力します.
出力:
9
 
関数の他の呼び出しを見てください.
   1: //#include <stdafx.h> // Visual Studio users need to uncomment this line
   2: #include <iostream>
   3:  
   4: int add(int x, int y)
   5: {
   6:     return x + y;
   7: }
   8:  
   9: int multiply(int z, int w)
  10: {
  11:     return z * w;
  12: }
  13:  
  14: int main()
  15: {
  16:     using namespace std;
  17:     cout << add(4, 5) << endl; // evalutes 4 + 5
  18:     cout << add(3, 6) << endl; // evalues 3 + 6
  19:     cout << add(1, 8) << endl; // evalues 1 + 8
  20:  
  21:     int a = 3;
  22:     int b = 5;
  23:     cout << add(a, b) << endl; // evaluates 3 + 5
  24:  
  25:     cout << add(1, multiply(2, 3)) << endl; // evalues 1 + (2 * 3)
  26:     cout << add(1, add(2, 3)) << endl; // evalues 1 + (2 + 3)
  27:     return 0;
  28: }
 
出力:
9

9

9

8

7

6
 
最初の3つの呼び出しは直接です.
ローカルコールも比較的簡単です.
   1: int a = 3;
   2: int b = 5;
   3: cout << add(a, b) << endl; // evaluates 3 + 5
 
この例では、add呼び出し、x=a、y=bとなる.a=3,b=5,add(a,b)=add(3,5)なので、その結果は8.
最初のテクニック的な語句を見てみましょう.
   1: cout << add(1, multiply(2, 3)) << endl; // evalues 1 + (2 * 3)
 
関数addをCPUが起動してみると、x=1,y=multiplly(2,3)となる.yは整数ではなく、関数の呼び出しです.したがって、CPUがadd関数を呼び出す前に、まずmultiplly()を呼び出します.ここで、z=2,w=3です.multiplly(2,3)の値は6で、この値はyに割り当てられます.したがってx=1,y=6,add(1,6)が呼び出され、7が生成される.7をcoutに渡す
または簡単な方法で(=>符号で求値を表す):
add(1,multiply(2,3)=>add(1,6)=>7
以下の文の中のadd関数の一つのパラメータはadd関数を呼び出します.
   1: cout << add(1, add(2, 3)) << endl; // evalues 1 + (2 + 3)
 
しかし、この文の実行は上記と一致しています.
簡単な表示:
add(1,add(2,3)=>add(1,5)=>6
 
関数を有効に使う
初心者にとっては難しい問題です.いつ、どのように関数を有効に使うかを知ることです.関数によって、あなたのプログラムを管理しやすく、繰り返して呼び出しやすい部分に分解できます.それらは簡単に組み合わせて、より大きな複雑な機能を実現できます.あなたのプログラムを小さい部分に分解すると、プログラム全体の複雑さが減ります.プログラムをより簡単に作成したり、修正したりすることができます.
 
C++を学ぶ時、3つの基本的な機能を含むプログラムをたくさん書きます.
  1.ユーザ入力のデータを読み出す
  2.入力した値から結果を計算する
  3.計算値を印刷する
簡単なプログラムについては、ユーザ入力データの読み取りは、一般的にmain()関数で行われます.しかし、ステップ2は関数の重要な部分である.関数は、ユーザーが入力したパラメータをパラメータとして計算した結果を返します.計算した結果は、(直接main()関数に印刷することができます.または計算結果が複雑で、特殊な印刷ニーズがある場合は、他の関数で印刷することができます.)
 
良い規則は各関数が一つ(一つだけ)の機能を完成することです.新しいプログラマはしばしば第2ステップと第3ステップを結合する.しかし、数値結果の計算と印刷は2つの異なる任務であり、これは一つの機能のみを実現するための提案に反している.理想的には、1つの関数が結果を計算し、この戻り値をどのように処理するかを調整者に決めさせます.