18
Help us understand the problem. What are the problem?

posted at

updated at

Organization

【初心者】関数・引数・戻り値を完全に理解した時の話

はじめに

プログラミングを始めて間もない時、必ず壁となる「関数、引数、戻り値」という概念。
プログラミングの勉強開始当初、理解力に乏しい僕はこれらの概念の理解に長い期間苦しんでいました。ですが、あるとき、ある人(誰か忘れましたが感謝してます)から受けた説明によって、一気に理解が進みました。その時の説明を忠実に再現したいと思います。

高校の数学

一旦、プログラミングから離れて高校の数学について考えてみます。

問題1

以下のような台形の面積yを求めよ
上底:a ㎝、下底:b ㎝、高さ:4 ㎝

答え(問題1)

台形の公式
面積 =「(上底 + 下底)× 高さ」÷ 2 を使うと

y = (a + b)× 4 ÷ 2
  = (a + b)× 2
y = 2(a + b)
面積yは2(a + b)cmと求めることができます。

また、これらは関数を使って以下のように表現したのを覚えていますか?
y = f(a,b) = 2(a + b)


では、以上を踏まえて次の問題です
(問題1の続きとして考えてください)

問題2

上底が6cm、下底が8cmの場合の面積yを求めよ
( f(6,8) = y はいくつになるか)

答え(問題2)

f(6,8) = 2(6 + 8)= 28
y = 28

プログラミングに置き換えると

問題2をプログラミングのコードで表すと
(公式を意味するcalcAreaを関数名とします。)

var y = calcArea(6,8)
console.log("台形の面積は" + y + "cm")

function calcArea(upperLine,bottomLine) {
   return 2 * (upperLine + bottomLine)
}

ーーーーーーーーーーー
台形の面積は28㎝
ーーーーーーーーーーー
と表示されます。

calcArea関数内で扱っているupperLine, bottomLineにはそれぞれ引数である6と8が入ります。

よって、

return 2 * (upperLine + bottomLine)

return 2 * (6 + 8)

となるわけで、計算結果の28が戻り値として返されます。

そして、返ってきた28をyに入れる

var y = calcArea(6,8)
 → y = 28 と同じ

最終的に面積yは28cmになります。

要するに、
y = f(x)
はプログラミングで言うところの
戻り値 = 関数(引数) と置き換えることができます。(多少無理やりですが。。)

また、既にお気づきかと思いますが、
y = f(x)の「f」は「function」の頭文字となっています。(初めてこれに気づいたとき感動しました。)

イメージ図

とはいえ、難しいことには変わりないので漠然とどのようなイメージを持てば良いのかを説明します。

まずは、工場に部品を渡す
GAS構想-6.jpg
すると、工場から部品を加工した完成品が返ってくる
GAS構想-7.jpg
これを今回の台形を求める問題に置き換えると
部品「6(上底)」と「8(下底)」を工場に渡す。
すると、工場で加工をした完成品「28」が帰ってくる
GAS構想-8.jpg

さらに、この図を一般化すると
引数を関数に渡すと、戻り値が得られる
(部品を工場に渡すと完成品が得られる)
GAS構想-9.jpg

以上のを踏まえた上で再度コードを確認します。
GAS構想-15.jpg
なんとなくイメージできましたか?

関数を使う目的?

なぜ関数を使うのか?どんなメリットがあるのか?
・コードを短くできる
・処理に名前をつけられる
コードが見やすくなる
それぞれのメリットについて説明していきます。

コードを短くできる

先ほどの例を使うと、
工場に渡す部品が変われば、返ってくる完成品も変わってきます。
(下の図では、f(6,8)=28 と f(7,9)=32 を例にしています。)
GAS構想-12.jpg
つまり、工場で部品を加工する回数(台形の面積を求める回数)が増えれば下の図のようになっていきます。
GAS構想-13.jpg
しかし、これだと1つの完成品を作るのに、1つの工場が必要となり効率が悪いですよね。
ということで、工場を1つにしました。これが関数です。
GAS構想-14.jpg

例えば、これまでと同じ条件下(高さが4㎝の台形)で
上底が10㎝、下底が15cmの台形の面積i
上底が20㎝、下底が25cmの台形の面積j
上底が30㎝、下底が35cmの台形の面積k
上底が40㎝、下底が45cmの台形の面積l
を求める場合、以下のコードだけで求められます。

var i = calcArea(10,15)
var j = calcArea(20,25)
var k = calcArea(30,35)
var l = calcArea(40,45)

function calcArea(upperLine,bottomLine) {
   return 2 * (upperLine + bottomLine)
}

処理に名前をつけられる

問題です。変数mには何を代入しているでしょうか?

var m = 4 * 5 / 2

???ですよね?
では、次の問題です。
変数mには何を代入しているでしょうか?

var m = caluTriangleArea(4,5)

function calcTriangleArea(bottomLine,height) {
   return (bottomLine * height) / 2
}

なんとなく分かったのではないでしょうか。
正解は、三角形の面積です。
関数名「calcTriangleArea」や引数の「bottomLine」、「height」からなんとなくイメージできたのではないでしょうか。
(bottomLine * height) / 2は紛れもなく(底辺×高さ)/ 2という三角形の面積を求める公式です。
このように、関数は処理に名前(意味)をつけることで,
処理の内容を明確にし、見やすいコードにすることができます。

おわりに

理解するまでは大変ですが、一度理解してしまえば、読めたり書けるコードの範囲が急激に広がると思います。腐らずにがんばりましょ。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Sign upLogin
18
Help us understand the problem. What are the problem?