3-2関数

プログラミングを初めて学ぶ際、最初につまづくのが関数や配列ではないでしょうか。関数の機能を一言で説明するとひとくくりの処理を一つにまとめることですが、プログラミング入門者の方はそのメリットを実感する前に文法でつまづいてしまうなどして、関数を敬遠することが多いように思います。
関数は、色々な場面で繰り返し使用される重要な処理を一つにまとめることができます。すると、その重要な処理に変更が必要になった場合や、そこのバグがひそんでいた場合などの修正が容易になります。理由は、その関数一つに修正を加えればいいからです。修正が必要になった処理が関数にまとまっておらず、たくさんの箇所に似たようなコードが存在すると、修正するのはとても大変です。
プログラミングの入門者、例えば単位を取るためにプログラミングの課題を提出する必要がある学生さんといった立場でも、関数はミスを減らしたり二度手間を防いだりすることに役立つ技術ではないでしょうか。


このページの内容

  1. 基本的な関数の使い方
  2. 関数を汎用的にする(引数のある関数)
  3. 複数の引数のある関数
  4. 引数のある関数の例1
  5. 引数のある関数の例2
  6. 引数のある関数の例3

基本的な関数の使い方

関数を使うには、まず「関数の処理内容を定義」します。次に「その関数の呼び出し」を行います。
「関数の処理内容を定義」することを「関数を宣言する」といいます。関数の宣言の例を下記に挙げます。

void circle() {
  ellipse(x, height/2, 50, 50);
} 

上記は、circleという名前の関数の宣言をするものです。関数の宣言は、「void 関数名(){」から始まり、「}」で終了します。
(「void」を「int」や「float」などに変更することも可能で、そういったものを「戻り値のある関数」と呼びますが、このページではそれは説明しません)
では「関数を呼び出す」にはどうすればいいでしょうか。関数を呼び出すには、その関数名を書くだけでよいのです。
下記が関数を使ったプログラミング例です。circle関数を呼び出すには「circle();」と書けばよいのです。

int x;

void setup() {
  size(480, 270);
  x = 0;
}
void draw() {
  background(200, 200, 200);  

  x++; 
  circle();  //関数の呼び出し

  if (x > width +25) {
    x = -25;
  }
}
//circle関数の定義
void circle() {  // 関数の宣言開始
  ellipse(x, height/2, 50, 50);
}  // 関数の宣言終了

上記プログラムは下記のように動作します。(画面を押すと停止し、長押しすると初期化されます。この動作は説明用に付け加えたもので、上記コードには含まれません)


関数を汎用的にする(引数のある関数)

赤い色のクマさんや緑色のクマさん、あるいは青色のクマさんなど、色だけを変えたクマさんを作りたい場合どうするべきでしょうか。色を指定する処理だけが異なり、ほかはまったく同じ内容の関数を三つ作るべきでしょうか? 実は、それはあまりよい方法ではありません。例えば、三種類ではなく、百、二百あるいは千、二千といった色のバリエーションが求められるようになったらどうでしょう。色ごとに関数を作っていたら、管理が大変です。バグがあったり、処理内容を変更したいととき、すべての関数を変更するのは大変な作業です。
こういった問題を解決する機能が関数には存在します。関数には引数というパラメーターを与えることが出来、それによって関数の機能を汎用的にすることができるのです。この機能を用いると、上記のようなケースでも作成する関数は一つで済みます。

関数に与えるパラメーターを「引数」と呼びます。関数を呼び出す際に与え、その関数の中で使用できる変数が引数です。
下記に使い方を示します。具体例を見ながら、使い方を覚えていきましょう。

引数のある関数を作るには、関数名のあとに続く波括弧「()」の中に引数を書きます。
下記は、引数のある関数の宣言の例です。

void circle(int hankei) {
  ellipse( x , height/2 hankei*2, hankei*2);
} 

上記例では、「int hankei」というのが引数です。引数のある関数を宣言するには、関数名のあとの丸括弧の中に、変数の型(int)と変数名(hankei)を書きます。

引数のある関数を呼ぶときは、下記のようにします。

circle(25);

引数はint型で宣言されているので、関数を呼び出す際に丸括弧の中にint型の数値を書きます。これにより引数であるhankeiという変数に、25という数値が設定され、circle関数の中で使用できるようになります。
関数を使った例を下記に載せます。

int x;
void setup() {
  size(480, 270);
  x = 0;
}
void draw() {
  background(200, 200, 200);
  x++; 
  circle(25);	//関数の呼び出し。引数のhankeiにint型の数値25を設定。
}

void circle( int hankei) {  //関数の宣言開始
  ellipse( x , y , hankei*2, hankei*2);//引数のhankeiを使って、円を描く。
}  //関数の宣言終了

上記のcircle関数は、円の半径を引数として与えることで、以前のcircle関数よりも汎用的になりました。circle関数を呼び出す際、引数であるhankeiの値を変えることで、色々な大きさの円を描くことができるからです。


複数の引数のある関数

下記は、複数の引数がある例です。
下記コード中のcircle関数では、「int centerX」,「 int centerY」,「 int hankei」という三つの変数が引数にあります。複数の引数がある場合は、このようにカンマで区切って書きます。
関数を呼び出す際は、丸括弧の中に書いた順に引数へ値が設定されます。下記の例では、xはcenterXに、height/2がcenterYに、25がhankeiに設定されます。

int x;
void setup() {
  size(480, 270);
  x = 0;
}
void draw() {
  background(200, 200, 200);  
  x++; 
  circle(x, height/2,25);	//関数の呼び出し
}

void circle(int centerX, int centerY, int hankei) {
  ellipse(centerX, centerY, hankei*2, hankei*2);
}

引数のある関数の例1

下記では、引数を変えて同じ関数を三度呼び出しています。引数の値が違うと、位置や大きさ、動く速さが変わります。引数の値によって、関数の動作にバリエーションを与えられることがわかるでしょう。

int x1,x2,x3;

void setup() {
  size(480, 270);
  x1 = 0;
  x2 = 0;
  x3 = 0;
}
void draw() {
  background(200, 200, 200);  

  x1++; //繰り返しのたびに1ずつ大きくなる
  x2+=2; //繰り返しのたびに2ずつ大きくなる
  x3+=3; //繰り返しのたびに3ずつ大きくなる

  //引数を変えて、同じ関数を呼び出す
  circle(x1, height/2-50,25);
  circle(x2, height/2,30);
  circle(x3, height/2+50,35);

}

/* 
 円を出力する関数
 centerX:中心のx座標
 centerY:中心のy座標
 hankei:半径
 */
void circle(int centerX, int centerY, int hankei) {
  ellipse(centerX, centerY, hankei*2, hankei*2);
}

(引数の用途は、上記のように注釈/* */で囲んでメモしておくとよいででしょう)
実行結果は下記のようになります。


引数のある関数の例2

下記は色の異なるクマさんを出力させる例です。引数に色を指定するパラメーターを追加するだけでそれができます。

int x;
void setup() {
  size(800, 600);
  x = 0;
}
void draw() {
  background(200, 200, 200);  

  x++; 
  kumasan(x, height/2-100,198, 59, 6);
  kumasan(x, height/2+100,100, 200, 6);

  if (x > width +75) {
    x = -75;
  }
}

/*
 クマさんを出力する関数
 centerX:顔の中心のx座標
 centerY:顔の中心のy座標
 red:毛皮の色の赤み
 green:毛皮の色の緑の強さ
 blue:毛皮の色の青み
 */
void kumasan(int centerX, int centerY,int red, int green, int blue) {
  fill(red, green, blue);  //毛皮の色
  ellipse(centerX- 50, centerY -60, 60, 60);  //左耳
  ellipse(centerX+ 50, centerY -60, 60, 60);  //右耳
  fill(250, 111, 96);  //ピンク
  ellipse(centerX- 50, centerY -60, 30, 30);  //左耳の内側
  ellipse(centerX+ 50, centerY -60, 30, 30);  //右耳の内側
  fill(red, green, blue);  //毛皮の色
  ellipse(centerX, centerY, 150, 150);  //顔
  fill(0, 0, 0);  //黒
  ellipse(centerX- 20, centerY -20, 20, 40);  //左目
  ellipse(centerX+ 20, centerY -20, 20, 40);  //右目
  line(centerX- 20, centerY + 30, centerX+ 20, centerY + 30);  //口
} 

実行結果は下記のようになります。


引数のある関数の例3

下記の例では、茶色のクマさんは左から右に、緑色のクマさんは上から下に移動します。

int x;
void setup() {
  size(800, 600);
  x = 0;
}
void draw() {
  background(200, 200, 200);  

  x++; 
  
  kumasan(x, height/2,198, 59, 6);//茶色いクマさんを呼ぶ処理
  kumasan(width/2, x,100, 200, 6);//緑色のクマさんを呼ぶ処理

  if (x > width +75) {
    x = -75;
  }
}

/*
 クマさんを出力する関数
 centerX:顔の中心のx座標
 centerY:顔の中心のy座標
 red:毛皮の色の赤み
 green:毛皮の色の緑の強さ
 blue:毛皮の色の青み
 */
void kumasan(int centerX, int centerY,int red, int green, int blue) {
  fill(red, green, blue);  //毛皮の色
  ellipse(centerX- 50, centerY -60, 60, 60);  //左耳
  ellipse(centerX+ 50, centerY -60, 60, 60);  //右耳
  fill(250, 111, 96);  //ピンク
  ellipse(centerX- 50, centerY -60, 30, 30);  //左耳の内側
  ellipse(centerX+ 50, centerY -60, 30, 30);  //右耳の内側
  fill(red, green, blue);  //毛皮の色
  ellipse(centerX, centerY, 150, 150);  //顔
  fill(0, 0, 0);  //黒
  ellipse(centerX- 20, centerY -20, 20, 40);  //左目
  ellipse(centerX+ 20, centerY -20, 20, 40);  //右目
  line(centerX- 20, centerY + 30, centerX+ 20, centerY + 30);  //口
}

実行結果は下記のようになります。