第十回-01 関数の基礎
関数とは C 言語プログラミングにおいて重要な単位である。
まず、C 言語によるプログラミングでは
「C 言語によるプログラムは関数の集まり」であることを頭に留めて欲しい。
本演習で初めて取り扱ったプログラムを眺めてみよう。
#include <iostream>
using namespace std;
int main(void){
// Your code here!
cout << "はじめてのコンソールアプリケーション\n";
}
ここで、
int main(void){
}
という構造に着目しよう。この構造のことを main 関数と呼ぶ。
つまり、C 言語によるプログラムは関数の集まりであると述べたが、
これまでコンソールアプリケーションで学んで来たのは関数 (main 関数) 一つだけのプログラムであった
というわけである。
本ページでは、main 関数以外にも複数の関数を持つプログラミングを学ぶ。
冒頭に述べたように、関数とは C 言語の最も基本的な単位であるため、関数を学ぶことでようやくプログラミングのスタートラインに立つことになる。
関数とは、1年生の Visual Basic for Applications (VBA) で学んだ
Sub プロシージャと
Function プロシージャとを統合した概念である。
Basic では別々に取り扱ったが C 言語ではこれらを区別しない。
VBA で学んだことと同じく、関数とはプログラムのあるまとまった単位をモジュールとしてまとめたもの、と考えるとよい。
そして、main 関数とはその様々な関数 (モジュール) を呼び出して、ある目的の処理を実行するもの、と考えられる。
なお、本ページではここまで「C 言語」という語句は用いたが「C++」という語句は用いていない。
それは実は
- C 言語 : 関数を主体としたプログラミング言語 (手続き型言語)
- C++ : オブジェクト(クラス)を主体としたプログラミング言語 (オブジェクト指向言語)
という違いがあるからである。
このように、C 言語と C++ ではプログラミングに対する基本的な考え方が異なるのだが、
C++ は C 言語の拡張として作られた言語であるため、C 言語風の記述もできる、という点に特徴がある。
C++ よりも後に登場した Java や C# はオブジェクト(クラス)を前提としているという意味でオブジェクト指向言語と呼ばれる。
ここまでで手続き型言語の入口までを取り扱ったことになる。
自分で関数を作成する場合、典型的には
の2つを記述する必要がある。
また、関数を作成する際、あらかじめ関数の引数 (ひきすう)と戻り値を決めなければならない。
引数と戻り値とは何かを理解するため、本日の演習では、数学の関数 y=f(x) のような関数をプログラミングで作成することにする。
ただし、数学における y=f(x) は「x と y の関係」を表す式だが、
プログラミングにおける y=f(x) は「f(x) の計算結果を変数 y に格納する」という意味を表すので注意が必要である。
このとき、x が関数 f(x) に対する引数、y に格納されるのが関数 f(x) の戻り値であると考えると、これ以後の解説が理解しやすくなるだろう。
関数を含むプログラムの構造は以下のようになる。
- 関数のプロトタイプ
- main関数 (いままで書いて来たもの)
- 関数の実装
#include <iostream>
using namespace std;
戻り値 関数名(引数リスト); // 自分で作る関数のプロトタイプ
int main(void) // いままで書いて来たmain関数
{
命令
}
戻り値 関数名(引数リスト) // これが自分で作る関数の実装
{
何らかの計算
return ... ; // 戻り値を return 文で返す
}
ただし、一般論のままでは理解が難しいだろうから、具体例で話を進めよう。
ここでは練習として
- double 型の引数 x に対して、x の 2 乗 (x2) を返す関数 square
を作成してみよう。
VBA では x^2 という記述で x の 2 乗を計算できたが、C/C++ では「^」という演算子をべき乗として使えず、
x*x と書かねばならないことを第九回課題で学んだのだった。
そこで、2 乗の関数を自分で作ってみよう、というわけである。
必要な全てのプログラムを先に提示すると以下のようになる。
#include <iostream>
using namespace std;
double square(double x); // 自分で作る関数のプロトタイプ
int main(void) // いつものmain関数
{
double y;
y = square(2);
cout << "yの値は" << y << "\n";
}
double square(double x) // これが自分で作る関数の実装
{
double val;
val = x*x;
return val; // 戻り値を return 文で返す
}
このプログラムを順に解説していく。
まず、4行目の以下の部分が関数のプロトタイプである。
double square(double x); // 自分で作る関数のプロトタイプ
関数 square は、double 型の引数 x を受け取り、結果である戻り値も double 型である、といことを示している。
また、main 関数の下にある以下の部分が square 関数の実装である。
double square(double x) // これが自分で作る関数の実装
{
double val;
val = x*x;
return val; // 戻り値を return 文で返す
}
1行目は関数のプロトタイプとほぼ同じであるが、セミコロン「;」が不要となっている。
x*x 、すなわち 引数 x の 2 乗を double 型の変数 val に格納し、val を return に渡し、戻り値としている。
「return 戻り値;」で戻り値が決まることが重要である。
なお、課題との兼ね合いで変数 val に格納してから val を 戻り値としているが、もっとシンプルに
double square(double x)
{
return x*x;
}
と書き、x*x を直接 return に渡しても同じである。
最後に、main 関数にある以下の部分が、作成した square 関数を利用している部分である。
y = square(2) は、square 関数に引数 2 を渡して実行しているので、2の2乗である 4 が変数 y に格納される。
double y;
y = square(2);
cout << "yの値は" << y << "\n";
なお、関数の戻り値を変数に格納せず、以下のように直接 cout に流し込んでも良い。
cout << square(2) << "\n";
さて、上記のプログラムを実行するには、これまで何度か行ったように「paiza.IO のプログラムを全てこちらで用意した内容で差し替える」という方針で記述する。
すなわち、まず paiza.IO のデフォルト状態のプログラム記述欄でキーボードで「Ctrl-a」を実行し、プログラム全体を選択する。
そして、キーボードのDeleteキーを押して、プログラム全体を削除する。
その結果、もちろん以下のようにプログラムが全く書かれていない状態になる。
その状態で、提示したプログラムをマウスで選択し、キーボードの Ctrl-c によりコピーする。
その後、何も書かれていない paiza.IO にてキーボードで Ctrl-v を実行してプログラム全体を貼り付けると以下のようになる。
実行すると出力に以下のように表示され、y = square(2) により 2 の 2 乗である 4 が y に格納されていることがわかる。
関数~課題を解くための準備→
オンラインコンパイラで C/C++ を自習しように戻る