Upload
-
View
151
Download
1
Embed Size (px)
Citation preview
© 2016 Embarcadero Technologies, Inc.
All rights reserved. Proprietary and confidential.
第4回
‟関数„
シーズン2:プログラミング言語をやさしく覚えよう
C++Builderの部
2© 2016 Embarcadero Technologies, Inc. All rights reserved. Proprietary and confidential. #embtwebi_jp
Delphi / C++Builder Starter チュートリアルシリーズ
シーズン2 :2017年1月23日 ~ 3月27日 全 9 回
時間 :毎週月曜 17 時 00分~17時 50分
Delphi 17時00分~17時20分 / C++Builder 17時30分~17時50分
ねらい :プログラミング言語をやさしく覚えよう
シーズン2
第1回 2017年1月23日 シューティングゲームのプログラム
第2回 1月30日 変数と 型
第3回 2月6日 条件 とループ
第4回 2月13日 関数
第5回 2月20日 配列 と 構造体
第6回 2月27日 文字列 と オブジェクト
第7回 3月6日 オブジェクト指向
第8回 3月13日 作ってみよう(仮)
第9回 3月27日 コミュニティ と 勉強会
セミナー情報 : 下記のWebサイト
http://forms.embarcadero.com/starter-tutorial-webinar
3© 2016 Embarcadero Technologies, Inc. All rights reserved. Proprietary and confidential. #embtwebi_jp
第4回「関数」
今日のねらい• 関数について知る• 関数と書き方
実施内容• 関数の書き方• 引数、戻り値• 宣言
4© 2016 Embarcadero Technologies, Inc. All rights reserved. Proprietary and confidential. #embtwebi_jp
無料版 C++Builder 10.1 Berlin Starter Edition 入手方法
• シリアルキーを知らせるメール内にも再ダウンロードリンク有• ダウンロード、インストール参考ブログ:https://goo.gl/CCBNdx
エンバ
Web製品
C++
Builder
Starter
バナー登録 Get
無料で使える開発環境をダウンロード
EDN*に登録済の方はEDNアカウントでダウンロード可
登録完了後、自動でインストーラーのダウンロード開始
インストール時にシリアルキーを入力
登録時のメールアドレスにシリアルキーが配信される
5© 2016 Embarcadero Technologies, Inc. All rights reserved. Proprietary and confidential. #embtwebi_jp
前提条件(引数)を与えると、それに基づいた結果(戻り値)が決まる処理のこと
例えば「自動販売機」を関数と考えてみると「代金」と「商品ボタン」を押すことが前提条
件にあたる
自動販売機で期待される処理結果は「選んだ商品が出る」、「釣銭を返却する」こと
戻り値(処理結果)引数(前提条件) 関数(自販機の内部処理)
関数とは?
お金 >=
商品の金額?
商品の在庫があるか?
釣銭は必要か?
代金を入れる
商品ボタンを押す
選んだ商品が出る
釣銭を返却する
6© 2016 Embarcadero Technologies, Inc. All rights reserved. Proprietary and confidential. #embtwebi_jp
C++における関数とは?
一連の処理を再利用可能とするために名前を付けたもの
関数を利用するには宣言と定義が必要
定義は関数を実際に実装したもので、宣言を伴う
関数宣言部だけを単独で書くこともできる(この目的は後述)
// 関数宣言と定義の例。宣言に続けて定義本体を {} で囲まれた中に記述する。戻り値のデータ型 関数名(引数1の型 引数1の変数名, …) // 関数宣言部{
// 関数の定義部// ここに実際に行う処理を書く
}
// 関数宣言部だけを記述するの例。定義部分の {} は含まないかわりに、セミコロンで終わる。戻り値のデータ型 関数名(引数1の型 引数1の変数名, …);
7© 2016 Embarcadero Technologies, Inc. All rights reserved. Proprietary and confidential. #embtwebi_jp
関数の実装例
コード例
int myIncFunction( int i ) // 関数名の前の int は、戻り値の型指定{
//戻り値は return で返す。return i + 1;
}
int myIncFunction2( int i )
{
} // return xx; が無い場合は return 0; が省略されているものとして扱う
8© 2016 Embarcadero Technologies, Inc. All rights reserved. Proprietary and confidential. #embtwebi_jp
関数の実装例
コード例
// 戻り値の型を void とすると、戻り値が返されないvoid myFunction(UnicodeString message)
{
ShowMessage( message );
}
// [C言語向け] 引数をとらない関数は、パラメータ部分に void と書くvoid Hello( void )
{
ShowMessage( L”Hello world” );
}
// [C++言語向け]引数をとらない関数は、パラメータ部分の void の記述をを省略してもよいvoid HelloCpp( )
{
ShowMessage( L”Hello C++Builder world” );
}
9© 2016 Embarcadero Technologies, Inc. All rights reserved. Proprietary and confidential. #embtwebi_jp
関数の引数と戻り値
関数の引数には関数宣言の型と一致する型のデータを渡す
関数の引数に一致しない型の値が渡された場合は……
• 型変換が可能な場合はキャストされるため、キャストの結果によっては意図とは異なる値になる
• 型変換が行えない場合はエラーとなる
関数使用時の引数(パラメータ)には式を使用可能
double DoubleValue(int iNum)
{
return iNum * 2;
}
void __fastcall TForm1.Button1Click(Tobject *Sender)
{
int i;
i = DoubleValue(8-1); // OK: 式の結果は整数値なので、これは関数の仕様と合致しているi = DoubleValue(10.2); // 値が正しく扱われない: 実数値はキャストで四捨五入されてしまい、”10” が関数に渡されるi = DoubleValue(L”文字列”); // コンパイルできない: 整数型をとるパラメータに文字列を渡しているので型が一致しない}
10© 2016 Embarcadero Technologies, Inc. All rights reserved. Proprietary and confidential. #embtwebi_jp
return - 関数の実行途中で関数を抜ける
関数の処理中に return [戻り値]; が出現したら、そこで関数を終了する
ループの深い階層からも抜けられる
関数の処理内容によっては、ループを抜ける前の後始末が必要なことも(後述)
void __fastcall TForm1::Button4Click(TObject *Sender){
UnicodeString str = L"Hello C++Builder";
for (WCHAR c : str ) {if ( c == 'B' ) return; // 文字 'B' を見つけたら関数を抜ける
Memo1->Lines->Add( Format(L"%s", ARRAYOFCONST(( c )) ) );}
Memo1->Lines->Add( L"END" ); // return で抜けた場合はこの処理に到達しない}
11© 2016 Embarcadero Technologies, Inc. All rights reserved. Proprietary and confidential. #embtwebi_jp
関数の記述順序
関数は、ソースコード内で定義された順番で利用できる
これでは実際の実装時にとても不便なので、定義の順番によらず利用する方法がある
double mySomeFunction (double i )
{
return i * 3.14;
}
void main( void )
{
double myvalue = mySomeFunction( 2 );
ShowMessage(
Format( L”%f”, ARRAYOFCONST((myvalue)) )
);
}
void main( void )
{
double myvalue = mySomeFunction( 2 );
ShowMessage(
Format( L”%f”, ARRAYOFCONST((myvalue)) )
);
}
double mySomeFunction (double i )
{
return i * 3.14;
}mySomeFunction() が main() より後に定義されているので呼び出し方が分からず、エラーになる
mySomeFunction() は main() より前に定義されているので関数が仕様どおりに呼ばれていることが検証できる
?
12© 2016 Embarcadero Technologies, Inc. All rights reserved. Proprietary and confidential. #embtwebi_jp
関数の記述順序
関数を予め宣言していれば、呼び出す場所と定義の順番によらず関数呼び出しが行える
double mySomeFunction(double i );
double mySomeFunction(double i )
{
return i * 3.14;
}
void main( void )
{
double myvalue = mySomeFunction( 2 );
ShowMessage(
Format( L”%f”, ARRAYOFCONST((myvalue)) )
);
}
double mySomeFunction(double i );
void main( void )
{
double myvalue = mySomeFunction( 2 );
ShowMessage(
Format( L”%f”, ARRAYOFCONST((myvalue)) )
);
}
double mySomeFunction (double i )
{
return i * 3.14;
}
関数宣言部関数宣言部
// 関数宣言部だけを記述するの例。定義部分の {} は含まないかわりに、セミコロンで終わる。戻り値のデータ型 関数名(引数1の型 引数1の変数名, …);
13© 2016 Embarcadero Technologies, Inc. All rights reserved. Proprietary and confidential. #embtwebi_jp
宣言と定義の分離でもたらされることは?
関数宣言が事前に行われると、関数定義の場所や順番によらず関数が呼び出せるようになる
関数宣言をソースコードから分離した別ファイル(ヘッダファイル)に記述すれば、別のソース
コードからも関数が呼べるようになる
// 作成中のプロジェクトに依存するヘッダファイルの参照// このプロジェクトだけで使用する関数宣言を記述する#include "Unit1.h"
// fmx.h というヘッダファイルの参照// マルチデバイスアプリケーション向け共通の関数宣言を含んでいる// 関数定義は、予めコンパイルされたものが開発環境に含まれている#include <fmx.h>
14© 2016 Embarcadero Technologies, Inc. All rights reserved. Proprietary and confidential. #embtwebi_jp
自らの関数を呼び出すことが可能「再帰呼び出し」
自らを呼び出す関数
ループの代わりに使用したり、フォルダ階層の読み取りなどに使用
int __fastcall TForm1::Recursive( int count ){
int retval = count - 1;
if ( retval > 0 ) Recursive( retval ); // 再帰呼び出しは実行条件を決めて行う
Memo1->Lines->Add( IntToStr( retval ) );return retval;
}
void __fastcall TForm1::Button1Click(TObject *Sender){
Recursive( 3 );
}
15© 2016 Embarcadero Technologies, Inc. All rights reserved. Proprietary and confidential. #embtwebi_jp
パラメータのデータ・変数の受け渡しについて
関数でパラメータにデータを渡す方法は
「値渡し」と「参照渡し」がある
デフォルトでは値渡し
• 呼び出し先の関数では渡された値を新たにコ
ピーしてから使用する
• 呼び出された関数が渡された値を変更しても、
呼び出し元の変数はその変更の影響を受けな
い
宣言部で変数名の前に & がついていた
ら参照渡しになる
• 参照渡しでは、変数の入れ物(保存場所)の
情報を受け渡す
• 呼び出された関数で変数の値を変更すると、
呼び出した側の変数も値が変わる
int i = 6;
/* x の値は参照渡しで実行した関数により 36 に変わる */参照渡しの関数( i );
void 参照渡しの関数(int &ref )
{ref = ref * 3;
}
int x, i = 4;
/* i は 4 のまま変化しない。x の値は 4 x 3 = 12 となる */x =値渡しの関数(i);
int 値渡しの関数(int value)
{int retval = 3 * value;
value = 0;return retval;
}
value という新しい変数に 4( = i ) がコピーされる
value は i とは別の変数なのでvalue を書き換えても 呼び出し元の
i は影響を受けない。
ref には、変数 i の入れ物(保存場所)が渡される
ref は i 自身なので、ref の値が変わる操作を行うと
i の値も変わる。
16© 2016 Embarcadero Technologies, Inc. All rights reserved. Proprietary and confidential. #embtwebi_jp
関数のオーバーロード
同じ名前でパラメータの型が異なる複数の関数を宣言・定義できる
呼び出しの際の引数の型に応じて実行する関数が自動的に選択される
同名のオーバーロード関数の型はすべて同じであることが必要
void __fastcall TForm1::overload_example( int n ){
Memo1->Lines->AddFormat( L"overload_example( int ) = %d", ARRAYOFCONST(( n )));
}
void __fastcall TForm1::overload_example( double n ){
Memo1->Lines->Add(Format(
L"overload_example( double ) = %.16f",ARRAYOFCONST(( n ))
));
}
void __fastcall TForm1::overload_example( int n ){
Memo1->Lines->Add(Format( L"overload_example( int ) = %d", ARRAYOFCONST(( n )) )
);}
void __fastcall TForm1::overload_example( double n ){
Memo1->Lines->Add(Format( L"overload_example( double ) = %.16f", ARRAYOFCONST(( static_cast<const long double>(n) )) )
);}
overload_example( 1 ); // 引数 int の関数を実行するoverload_example( 3.141592 ); // 引数 double の関数を実行する
17© 2016 Embarcadero Technologies, Inc. All rights reserved. Proprietary and confidential. #embtwebi_jp
デフォルトパラメータ
関数のパラメーターにデフォルト値を代入式であらかじめ設定可能
関数呼び出し時に、デフォルト値をもつパラメータは省略可能
デフォルト値はパラメーターリストの後ろにまとめる
オーバーロードを併用する場合は、呼び出しが区別できるように実装する
int __fastcall TForm1::DefaultParameter( int numA = 2, int numB = 3 ){
int total = numA * numB;return total;
}
void __fastcall TForm1::Button1Click(TObject *Sender){
/* 以下の3つは同じ結果となる */
Memo1->Lines->Add( IntToStr(DefaultParameter()) );Memo1->Lines->Add( IntToStr(DefaultParameter( 2 )) );Memo1->Lines->Add( IntToStr(DefaultParameter( 2, 3 )) );
}
18© 2016 Embarcadero Technologies, Inc. All rights reserved. Proprietary and confidential. #embtwebi_jp
__fastcall
C++Builderのイベントハンドラに自動的につけられる修飾子
C++Builderで関数を作るときにはつけるものと理解しておく
正確な話は…
• 関数実行時の引数の渡し方の規約
• その他の修飾子
• パラメータのスタック経由渡し (C言語標準の cdecl)
• パラメータのレジスタ経由渡し (fastcall, stdcall)
http://docwiki.embarcadero.com/RADStudio/ja/Fastcall、_fastcall
http://docwiki.embarcadero.com/RADStudio/ja/関数修飾子http://docwiki.embarcadero.com/RADStudio/ja/言語混在時の呼び出し規約
19© 2016 Embarcadero Technologies, Inc. All rights reserved. Proprietary and confidential. #embtwebi_jp
他、関連する機能など
インライン化 (inline 指令)
• コンパイル時に関数を、当該呼び出し箇所にインライン化
• http://docwiki.embarcadero.com/RADStudio/ja/Inline
DLL読み込み
• http://docwiki.embarcadero.com/RADStudio/ja/RAD_Studio_での_DLL_の使用(C++)
• http://docwiki.embarcadero.com/RADStudio/ja/チュートリアル:C++Builder アプリケーショ
ンでダイナミック リンク ライブラリを使用する
20© 2016 Embarcadero Technologies, Inc. All rights reserved. Proprietary and confidential. #embtwebi_jp
本日のセミナー内容は弊社ブログに掲載予定
[コミュニティ]↓
[日本人ブログ]
実施内容の再視聴
皆さんが見ているWebページの下に、順次アップロード
エンバカデロWebサイト : http://forms.embarcadero.com/starter-tutorial-webinar
[リソース] – [イベント]の「Delphi / C++Builder Starter チュートリアルシリーズ」ページ
実施内容サマリー
• Community embarcadero (コミュニティ エンバカデロ)にWebリンク、サンプルコード情報等
http://community.embarcadero.com/
「エンバカデロ」で検索
21© 2016 Embarcadero Technologies, Inc. All rights reserved. Proprietary and confidential. #embtwebi_jp
第4回「関数」まとめ
今日のねらい• 関数について知る• 関数と書き方
実施内容• 関数の書き方• 引数、戻り値• 宣言