[ 前へ | 目次 | 次へ ]

関数

ここでは、処理をまとめる重要な手段である、関数の仕組み扱います。


関数

例えば、ある適当な数a,b に対して、「 a*a+b*b 」といった値をプログラム中のいくつもの箇所で行いたい場合があったとします。

このような場合、必要な箇所すべてに「 a*a+b*b 」を書いていってもいいのですが、それは少し面倒です。 特に、あとでやはり「 a*a+b*b-2 」にしたい、等といった事が生じると、いくつもの箇所を書き直す事になってしまいます。

このような場合は、あらかじめ関数を定義しておくと便利です。関数は、変数の組を受け取って、 それに対する処理を行い、結果を出力するための仕組みです。

関数は、以下のような文法で定義されています:

戻り値の変数型   関数名( 引数1, 引数2, … ) {
    処理内容 ;
    return 戻り値 ;
}

ここで引数とは、関数が処理に使用するために受け取る変数のことです。 恐らく「引き受ける数」などから省略された用語なので、「ひきすう」と発音します。

また、戻り値とは、関数が処理結果として出力する変数の事です。 恐らく「関数から戻ってくる値」などから省略された用語です。

a*a+b*b を処理する関数の例

例として、ある適当な整数a,b に対して、「 a*a+b*b 」といった値を返す関数を定義してみましょう:

この関数は、int 型のa,b を受け取り、内部でvalue という値にa*a+b*b を計算して代入し、それを戻り値として返します。

それでは、実際にこの関数を、プログラム中から呼び出してみましょう。

プログラム中から関数を呼び出すには、そこに「関数名の後にカッコを付けたもの」を記述します。 そしてそのカッコの中に、引数をカンマ記号「 , 」で区切って指定します。

以下のように記述し、実行してみてください:

- 実行結果 -

5

これを実行すると 5 が表示されます。関数fun の中で正しく1*1+2*2 が実行され、戻り値として返ってきた事が分かります。

何も返さない関数

関数は、必ずしも戻り値を返す必要はありません。

戻り値を返さない場合は、「 void 型 」で関数を宣言します。 void とは英語で空(から)の意味で、void 型はその名の通り、戻り値が空である事を意味する、特別な型です。

引数を持たない関数

引数についても、何も持たない事が可能です。その場合は、引数記述部を空白にします。

配列を引数とする関数

関数の引数には、配列を指定する事もできます。それには以下のように記述します:

または、変数型の部分にブラケットを付けた、以下のような記述も可能です。

これで、int 型の配列a,b を引数に受け取れます。 配列の要素数は、プログラム中から呼び出し時に入力された引数のものとなります。 必要であれば、length( array[ ], int dim ) 関数で要素数を確認する事もできます。

上のように配列を引数に渡した場合、それは値渡しとなります。 つまり、配列の全要素の値がコピーされます。そして、関数内で引数に加えた変更は、呼び出し元に反映されません。

C系の他言語との互換性には注意が必要

多くのC言語系の他言語では、配列は参照型であり、配列引数に対する関数内での変更が、 呼び出し元に反映されます(※ 参照の値渡し)。

一方、VCSSLでは配列も値型であり、明示的に参照渡しを行わない場合は、 配列引数の受け渡しも単純な値渡しとなります。つまり変更は呼び出し元に反映されません。

この違いは、C系他言語との互換性において、特に注意が必要な点となっています。

配列を戻り値とする関数

VCSSL の関数は、配列を戻り値に返す事もできます。それには以下のように、関数の型宣言の部分に [ ] を付けて宣言します。

これで、戻り値に配列を返す事ができます。プログラム中からこの関数を呼び出し、戻り値を配列に代入すると、その配列の要素数は戻り値と同じものに変更されます。

引数の値渡しと参照渡し

関数の引数は、上の例のように普通に定義すると、呼び出し時に値がコピー(代入)される 「 値渡し 」となります。

つまり、関数内で引数の値を変更しても、それが呼び出し元には反映されません。

それに対して、変数名の前にアンパサイド記号「 & 」 を付けて定義すると、 呼び出し元にも変更が反映される「 参照渡し 」となります:

- 実行結果 -

i=0   j=1

上の例では、VCSSL コンソールに「 i=0 j=1 」と表示されます。参照渡しで jの変更が反映されました。

配列の参照渡し

配列をまるごと参照渡しする事もできます。その場合は、以下のように記述します。

それに対して、変数名の前にアンパサイド記号「 & 」 を付けて定義すると、 呼び出し元にも変更が反映される「 参照渡し 」となります:

- 実行結果 -

i=0   j=1

このように、引数名とアンパサイド記号「 & 」 をまとめて ( ) でくくります。 ただし参照渡しには、後に述るように、いくつかの注意点や制限、デメリットなどがあります。 それについては配列の場合でも同様です。

参照渡しの注意点

VCSSLにおける参照渡しの機能はまだ新しく、処理系の実装に依存している不完全な挙動があります。 この点に関しては、使用の際に注意が必要です。

配列要素の参照渡しには特に注意が必要

まず注意が必要なのは、配列の要素を参照渡しする場合です。

例えば、参照渡しで引数を受け取る関数 fun があったとして、fun( a[ i ] ) ように配列の要素を参照渡しした場合、 関数の処理が終わるまで、関数外においてインデックス i の値を変更してはいけません。

つまり、fun( a[ i ] ) をコールした時点で i が 2 であったものを、 処理途中に外部から i を 3 に切り替えるような事をしてはいけません。 実際にこのような処理を行った場合、fun内部での(参照渡しで受け取った)引数が、 ずっと a[ 2 ] を参照し続けるのか、もしくは i の変更後から a[ 3 ] を参照するよう切り替わるのかは、 現時点で処理系依存です。

現在のVCSSLエンジンの実装では後者の挙動が中心です。 しかし他言語では前者の挙動が一般的であるため、V CSSLエンジンでも今後は前者の挙動に切り替わっていく可能性があります。

上述のような、配列要素の参照渡しについては、構造体やそのメンバに関しても同様に注意が必要です。 例えば参照渡しで引数を受け取る関数funに、 fun( a[ i ].b[ j ].c[ k ] ) のように引数を渡した場合、 その関数の処理が終わるまで、i も j も k も、値を変更してはいけません。

最後に、配列要素を参照渡しする場合、その関数の処理が終わるまでは、alloc などで配列を再確保してはいけません。

参照渡しができない場合

参照渡しは、常に行えるわけではなく、できない場合もあります。

例えば別の関数の戻り値を、参照渡しで直接受け取る事はできません。 そういった場合は、関数の戻り値を一度別の変数に格納してから、その変数を参照渡しする必要があります。

参照渡しのデメリット

参照渡しで受け取った引数に対する演算は、処理効率が悪く、一般に処理速度が低下します。 引数に渡す変数のメモリーサイズが大きい場合は、値渡しよりも参照渡しのほうが、 データのコピーが不要になる分、軽くなる場合がありますが、 そうでない場合、VCSSLにおける参照渡しはパフォーマンス面で不利になります。

また、普通に値渡し引数を受け取って、結果を戻り値で返せば済むような場面などで、 あまり頻繁に参照渡しを用いると、プログラム全体の可読性を低下させる要因になり得ます。



スポンサーリンク



スポンサーリンク

この階層の目次
お知らせ

各ソフトウェアの最新版を一括でリリース、OpenJDKのJava実行環境(JRE)に対応
2019年03月06日 - RINEARNでは3月6日に、主要なソフトウェアの最新版を一括でリリースしました。今回のアップデートには、以前お知らせした、OpenJDKで生成したJREへの対応が含まれています。その概要等をお知らせします。

次回のVCSSL 3.4.10において、関数1個の挙動に非互換な修正が適用されます
2019年02月12日 - VCSSLの次回の正式リリース版3.4.10において、これまでドキュメントと実際の挙動が異なっていた描画系の関数1個に、非互換な修正が適用されます。その詳細と、使用コードでの対応方法について解説します。

RINEARNのソフトウェア向けにOpenJDKで生成したJava実行環境(JRE)の提供を開始
2019年02月06日 - Javaのリリースモデル変更への対応として、OpenJDKのjlinkツールを用いて、RINEARNのソフトウェア実行用に生成したJava実行環境(JRE)の提供を開始しました。その詳細と、今後の方針について解説します。

新着
画像の矩形(四角形)領域を切り抜く簡易ツール(複数ファイル一括処理版)

フォルダ内にある全ての画像ファイルを開き、その中の矩形(四角形)領域を切り抜いて、別のフォルダに保存する簡易ツールです。
2019年03月15日
画像の矩形(四角形)領域を切り抜く簡易ツール

画像ファイルを開き、その中の矩形(四角形)領域を切り抜いて保存する簡易ツールです。
2019年03月14日
入力された数式を積分して値とグラフを表示するツール

画面上で数式を入力すると、それを数値的に積分し、値とグラフを表示してくれるGUIツールです。
2019年01月20日
z = f(x,y,t) の形の数式を3Dグラフとしてアニメーション描画するツール

入力欄に z = f(x,y,t) の形の数式を入力すると、それを3次元のグラフにアニメーション描画してくれる簡易ツールです。
2018年11月26日
y = f(x,t) の形の数式を2Dグラフとしてアニメーション描画するツール

入力欄に y = f(x,t) の形の数式を入力すると、それを2次元のグラフにアニメーション描画してくれる簡易ツールです。
2018年11月25日
開発元Twitterアカウント

スポンサーリンク