ページ 11

引数のある関数

Posted: 2011年9月18日(日) 17:25
by 隠蔽
突然で非常に申し訳ないのですが質問させてもらいます

引数のある関数ってありますよね?
この関数から呼ぶときは値を渡したい、あの関数から呼ぶときは値を渡したくないということがあります
実引数が記述されている関数を値を渡さずに呼び出すことは可能でしょうか?
可能なら方法を教えていただきたい

どうかよろしくお願いします

Re: 引数のある関数

Posted: 2011年9月18日(日) 18:07
by softya(ソフト屋)
隠蔽 さんが書きました:この関数から呼ぶときは値を渡したい、あの関数から呼ぶときは値を渡したくないということがあります
実引数が記述されている関数を値を渡さずに呼び出すことは可能でしょうか?
基本的には、その状況は関数自体の設計が異常だと思います。
引数のある関数と無い関数は別の関数にする方が良い設計では無いでしょうか?

ちなみに、トリッキーな手段を使わないと出来ません。

【追記】
それと何となくですが文体から前に質問された否妻さんとお見受けしますが、もしそうならフォーラムルールに書かれていますが名前を変更しないようにお願いします。
もし違ったら申し訳ありません。

Re: 引数のある関数

Posted: 2011年9月18日(日) 18:20
by box
隠蔽 さんが書きました: 実引数が記述されている関数を値を渡さずに呼び出すことは可能でしょうか?
念のためにおたずねします。
実引数と仮引数とがゴッチャになったりはしていないですよね。

Re: 引数のある関数

Posted: 2011年9月18日(日) 19:37
by 隠蔽
お二人がた、ありがとうごいます
実引数とか引数はご心配の通りごちゃになっておりました
名前の方はこちらの名前で統一します 申し訳ないです

実は今回の質問を詳しく説明しますと
当たり判定関数から描画関数に「当たったフラグ」を渡して絵を表示させようとしていたのです
でも描画関数はmain関数にも書かなくてはならないと思っていたのです
よく考えてみたらmain関数に書く必要がない気もしてきました 書かなくてもいいのですか?


それと、サンプル館の[削除 by softya]のプログラムを見ていて気になったのですが 
このゲームには二つの構造体がありますよね どこらへんで実体が宣言されていますか?


2つも質問がありますがどうか教えてください

Re: 引数のある関数

Posted: 2011年9月18日(日) 19:42
by 隠蔽
とんでもない誤字がありました
間違えた自分が言うのもなんですが、
すぐに訂正していただけると助かります
本当にごめんなさい 

Re: 引数のある関数

Posted: 2011年9月18日(日) 20:48
by softya(ソフト屋)
隠蔽 さんが書きました:当たり判定関数から描画関数に「当たったフラグ」を渡して絵を表示させようとしていたのです
でも描画関数はmain関数にも書かなくてはならないと思っていたのです
よく考えてみたらmain関数に書く必要がない気もしてきました 書かなくてもいいのですか?
前にも言いましたが質問が抽象的なので、答えを抽象的に書かざるおえません。
当たったフラグを渡して描画するよりも、当たったフラグが何らかのエフェクトをするならエフェクト管理のモジュール(cpp)で描画すべきだと思います。
エフェクトの発生関数は呼び出す必要があると思います。
ある程度の規模のプログラムでmain関数内で描画処理を直接呼び出す事は無いでしょう。

サンプル館の件に貸しては昔のプログラム構造は見本にしないで(by Dixq(管理人)さん)との事ですので、あんまり真似されないほうが良いと思いますよ。
ちなみに、GLOBALで実体とextern参照を切り替えていたはずです(もしかしたら勘違いかも)。龍神録はそうなっています。

Re: 引数のある関数

Posted: 2011年9月18日(日) 21:04
by 隠蔽
「当たったフラグが何らかのエフェクトをする」とはどういった意味でしょうか?
エフェクトって言ったら自分はキャラの周りに出る火花などをそうぞうするのですが
エフェクトをするとはどういうことですか?

Re: 引数のある関数

Posted: 2011年9月18日(日) 21:13
by 隠蔽
もう一つ言わせてください
自分は敵との当たり判定ではなくて
主人公があるところに到達したらマップを切り替えるための当たり判定なのですが
その場合でもエフェクト関数とやらで解決できるのでしょうか

先ほどと合わせて2点、お願いします

Re: 引数のある関数

Posted: 2011年9月18日(日) 21:14
by softya(ソフト屋)
隠蔽 さんが書きました:「当たったフラグが何らかのエフェクトをする」とはどういった意味でしょうか?
エフェクトって言ったら自分はキャラの周りに出る火花などをそうぞうするのですが
エフェクトをするとはどういうことですか?
少し言い方が悪かったですね。
誤:当たったフラグが何らかのエフェクトをする
 ↓
正:当たったフラグで何らかのエフェクトをする

当たった状態を描画関数に渡す以上は、何らかのエフェクトをする気なのではないかと考えたのですが、「当たり判定関数から描画関数に「当たったフラグ」を渡して絵を表示させようとしていたのです」の動作を具体的に説明してもらえますか?

Re: 引数のある関数

Posted: 2011年9月18日(日) 21:16
by softya(ソフト屋)
隠蔽 さんが書きました:自分は敵との当たり判定ではなくて
主人公があるところに到達したらマップを切り替えるための当たり判定なのですが
その場合でもエフェクト関数とやらで解決できるのでしょうか
その当たりの判定状態を描画関数に渡す必然は有りませんね。
描画関数ではなく、マップの切り替え関数やマップ管理の関数の役割りでは?

Re: 引数のある関数

Posted: 2011年9月18日(日) 23:18
by 隠蔽
マップ管理関数と描画関数とエフェクト関数は別として考えていらっしゃいますか?
自分の場合は絵をかく関数はすべてまとめたいと思っています
ソートの時に便利だから

リュウジンロクを見て真似るつもりですが
リュウジンロクでは当たり判定と描画の関係はどうなっているのですか?
すいません 勉強不足ですがこれだけは聞いておきたいです

Re: 引数のある関数

Posted: 2011年9月18日(日) 23:50
by softya(ソフト屋)
描画関数に他の処理が入るのはお勧めできません。
当然ながら龍神録も移動・当たり判定その他の処理は描画関数と分離されています。
描画関数も背景・敵・弾・自機など細かく分かれています。
関数の名前と中身が食い違うことはバグの混入の原因となり、1つの関数に集めることで関数の肥大を招きますので自分でもコードの内容を把握することが難しくなるので良いことは何もありません。

Re: 引数のある関数

Posted: 2011年9月19日(月) 08:42
by 隠蔽
今さっき、リュウジンロクを見てきましたが表示フラグはグローバルになっていませんか?(構造体だったか?)
解決したトピックに書くのもなんですか描画関数でソートを行ってはいけないと仰いましたよね

ソフトやさんならどこでソートさせるのですか?
(y座標基準に奥から描画していきます)

Re: 引数のある関数

Posted: 2011年9月19日(月) 10:09
by softya(ソフト屋)
隠蔽 さんが書きました:今さっき、リュウジンロクを見てきましたが表示フラグはグローバルになっていませんか?(構造体だったか?)
解決したトピックに書くのもなんですか描画関数でソートを行ってはいけないと仰いましたよね

ソフトやさんならどこでソートさせるのですか?
(y座標基準に奥から描画していきます)
龍神録はDixq(管理人)さんも分かりやすさ優先でグローバル変数を多用していますが、あまりオススメできないと公言しています。
で、グローバル変数と描画処理の話は別の問題なので今回は描画処理に絞って話をします。

ソート自体は、描画処理の前に終わらせておいて描画リストを作成した上で描画は描画リスト順に行うだけで良いのでは無いでしょうか?

[イメージ]
移動・当たり判定他
 ↓
描画ソート
 ↓
背景描画
 ↓
ソート順の描画

Re: 引数のある関数

Posted: 2011年9月19日(月) 21:06
by 隠蔽
トピックタイトルの話を戻すようで悪いのですが
リュウジンロクではグローバル変数なので値を関数に渡す必要がありませんよね
もし画像ハンドルとかフラグ変数などローカルにしようとした場合、
mainからは呼ぶときは値はいりません 
どうするのでしょう?というか皆さんどうしてるのでしょう?
そもそもmainから呼び出すという構成の仕方から
間違っている気がしてならないのですがどんな構成なのでしょう?

Re: 引数のある関数

Posted: 2011年9月19日(月) 22:39
by softya(ソフト屋)
構造化プログラミングの話になるのですが、モジュール化・隠蔽が基本要素で強強度(凝集度)・疎結合を目指すのがバグの少ない良いプログラムを書く秘訣です。

「構造化プログラミング」
http://www.baika.ac.jp/~kayama/program/ ... struct.htm
つまり、
・モジュール化 機能単位にファイルと関数を分ける。
・隠蔽 なるべく外に不要な情報は出さない
・疎結合 なるべくモジュール間のデータ関係性を弱くする。グローバル変数などもっての他。
・強強度(凝集度) 関数の機能がいかに純化しているか。

「★SEの残業しない仕事術★ 上村敏彦のブログ : 設計の仕方」
http://blog.livedoor.jp/gaseidou2/archi ... 19230.html
「モジュールの強度と結合度<システムの調達<Web教材<木暮」
http://www.kogures.com/hitoshi/webtext/ ... index.html

例を挙げると
プレーヤ処理というファイルを作ります。Player.cpp
画像イメージや座標などは基本的にPlayer.cpp内部に保持します。
外部に公開する関数は、
Player_Init();
Player_Calc();
Player_Draw();
が基本関数です。これ以外にも外部に公開する関数や公開しない関数は出てきます。
なすべく他のモジュールとは関係を持ちたくないですが、マップと敵のモジュールとはインターフェイスが必要でしょう。

変数については基本はファイルスコープで、必要がないなら極力内部関数とします。
グローバルスコープの変数は通常設けません。

main自体も
「C言語~ゲームプログラミングの館~ 34. メイン関数の書き方。」
http://dixq.net/g/37.html
に有るように、mainはタイトル・本編の切り替えなど基本的な切り分けだけに特化してゲームの根本部分は別の関数で記述するのが普通です。

あと私の書いたRPG講座ですが、モジュール化をかなり意識しているのでプログラム構造の参考になると思います。
「マイ 日記 • C言語交流フォーラム ~ mixC++ ~」
http://dixq.net/forum/blog.php?u=114&sd=a&c=2
グローバル公開しているのは、キー入力などのごく一部だけです。

Re: 引数のある関数

Posted: 2011年9月19日(月) 23:05
by 隠蔽
またまたすいません
ソフト屋さんのあげてくれた講座を途中まで見たのですが
char_load関数で構造体を返していますが呼び出し元はmain関数でしょうか?

全部は見てないのですが
描画メインからロードを呼び出して描画メインに値を返して、そこから描画関数に渡す
となっているのでしょうか? 全部、見てないから分からないんですけどね
(キャラ管理の続きがどこに書いてあるかわからないもんで)

Re: 引数のある関数

Posted: 2011年9月19日(月) 23:49
by softya(ソフト屋)
自キャラの場合は、最終的にはgameMain.cpp内にあるファイルスコープの構造体に格納しています。
なので、呼び出し元はgameMain.cpp内にあるGameMain_Init()関数です。
GameMain_Init()を呼び出してるのは、MainInit()関数でこれを呼び出しているのがmain()関数です。

char_Load関数自体は疎結合な関数で汎用性があるので、自キャラ以外に町人の読み込みでも使用しています。
この場合、町人のデータはmap.cpp内にあるファイルスコープの構造体に格納しています。

Re: 引数のある関数

Posted: 2011年9月20日(火) 00:26
by 隠蔽
ソフト屋さんのRPGの全ソースをダウンロードさしていただきました
ロードは見つかったのですが(プレイヤーオブジェに画像ハンドルを代入)
プレイヤーオブジェをどうするのかと探してみたのですが今度は描画関数の呼び出しが
どこにあるか分かりません
幾度もお手数をかけますが教えてくださいませんか?

Re: 引数のある関数

Posted: 2011年9月20日(火) 00:38
by softya(ソフト屋)
char_Draw()で描画しています。
PlayerObjにchar_Load()したキャラクタオブジェクトを代入していますので、これを表示にも使いますから検索キーとしてPlayerObjが使えますよ。

Re: 引数のある関数

Posted: 2011年9月20日(火) 17:10
by 隠蔽
ロード関数から構造体を返していますが
ポインタで渡して直接、値を書き換えるというやり方じゃダメなのでしょうか?
自分は初心者なので効率などはさっぱりですが見やすい気がして

Re: 引数のある関数

Posted: 2011年9月20日(火) 17:33
by softya(ソフト屋)
呼び出し元には構造体のメンバは隠蔽されていますので中身を意識させないと行った手法を使っています。
これも隠蔽の一貫です。

【追記】
ちなみに戻しているのは構造体では無く構造体のポインタです。
fopen()がFILE*を返すのと似た考え方です。

Re: 引数のある関数

Posted: 2011年9月21日(水) 15:02
by 隠蔽
キャラの描画部分が見当たらないのですがchar_Drawはどのファイルに記述されていますか?

それと構造体をポインタで仰いましたが意味が分かりません すいません
自分の考えていたものと違ったもので・・・どういうことですか?ファイルネームがポインタだから?

Re: 引数のある関数

Posted: 2011年9月21日(水) 15:40
by softya(ソフト屋)
最終バージョンを落とされましたか?

「簡単RPG講座13-8。戦闘システムの8(第一部完結編)。 • C言語交流フォーラム ~ mixC++ ~」
http://dixq.net/forum/blog.php?u=114&b=1859&c=2

ご質問のchar_Draw()はchar_Load()と同じchar.cppに記載されています。
隠蔽 さんが書きました:それと構造体をポインタで仰いましたが意味が分かりません すいません
自分の考えていたものと違ったもので・・・どういうことですか?ファイルネームがポインタだから?
ファイルネームがポインタである事は何も関係有りません。

char_Load()の戻り値は、CHAR_OBJECTです。

コード:

extern CHAR_OBJECT char_Load(char *FileName,int xnum,int ynum);
と定義されています。

ヘッダではCHAR_OBJECTは、、

コード:

//	キャラ管理オブジェクト
typedef struct tag_CharObject *CHAR_OBJECT;
とtypedef定義されています。つまり、struct tag_CharObject *でstruct tag_CharObjectのポインタです。
なので、char_Loadは戻り値として構造体tag_CharObjectのポインタを返していると言うことです。

struct tag_CharObjectキャラクタ管理の構造体ですが、

コード:

//	キャラ管理オブジェクトの構造体
struct tag_CharObject {
	int xnum;		//横方向の数。
	int ynum;		//縦方向の数。
	int animPtn;	//アニメーションのパターン
	int muki;		//向き
	int *images;	//プレーヤーキャラクタのイメージ配列
};
と言うメンバを持っています。このメンバは隠蔽のためchar.cpp外には公開していません。
char_Load()のソースコードで分からないところを有るんじゃないかと思いますが、そこを聞いてもらった方が良いと思います。
構造体tag_CharObjectの実体を動的確保しているmallocとかが理解出来ないのでしょうか?

Re: 引数のある関数

Posted: 2011年9月21日(水) 19:13
by 隠蔽
いえ、mallocの関数は知っている気がしますがバイトを書くとメモリをアレしてくれるやつですよね
でも、見るまで使い方はわかりませんでした


描画関数のことですが呼び出し元を教えてくれませんか?
ゲームメイン.cppのファイルで見当たらなかったので


それと、さっき思ったのですがプロトタイプ宣言にエクステーンっているんですか?
関数の定義って一か所にしかない気がするのですが

Re: 引数のある関数

Posted: 2011年9月21日(水) 19:22
by softya(ソフト屋)
隠蔽 さんが書きました: (1)いえ、mallocの関数は知っている気がしますがバイトを書くとメモリをアレしてくれるやつですよね
でも、見るまで使い方はわかりませんでした

(2)描画関数のことですが呼び出し元を教えてくれませんか?
ゲームメイン.cppのファイルで見当たらなかったので

(3)それと、さっき思ったのですがプロトタイプ宣言にエクステーンっているんですか?
関数の定義って一か所にしかない気がするのですが
(1)肝心のchar_Load()のやっていることは結局理解できたのでしょうか?

(2)VC++なら関数名を選んで「呼び出しブラウザ」で「呼び出し元の表示」を行ってください。
あるいは「全ての参照の検索」を使います。
私に聞くより、ツールを使いこなしてくださいね。

(3)それは趣味です。外部関数だよって明示宣言ですね。実際はいらないです。
「関数の定義って一か所にしかない気がするのですが」に関してはヘッダに書いてあるので一箇所ではなくインクルードしているcpp全部が対象になります。
外部公開しない関数は.cppにstaticでプロトタイプ宣言してあります。

Re: 引数のある関数

Posted: 2011年9月21日(水) 20:41
by 初級者
外国語をカナで書くのはなかなかむずかしいですね。
externのカナ表記を原語の発音にできるだけ近づけるとすると、
イクスターンあるいはエクスターンあたりでしょうか。
エクステーンにはならないと思います。

Re: 引数のある関数

Posted: 2011年9月21日(水) 22:01
by 隠蔽
ロード関数に関しては理解はできたのでしょうかね
分割ロードに使う縦と横をもらってメモリを確保して画像を読み込ませている 構造体を返す
まあ、書けって言われたら無理なんですけどね

自分はBCを使っているのですがVCばかりですしBCは切った方がいいのでしょうか?
というかBCC Developerにもそんな機能ありませんか?


エクスターンですか・・・もうカタカナ表記は一生しません

Re: 引数のある関数

Posted: 2011年9月21日(水) 22:10
by softya(ソフト屋)
隠蔽 さんが書きました:(1)ロード関数に関しては理解はできたのでしょうかね
分割ロードに使う縦と横をもらってメモリを確保して画像を読み込ませている 構造体を返す
まあ、書けって言われたら無理なんですけどね

(2)自分はBCを使っているのですがVCばかりですしBCは切った方がいいのでしょうか?
というかBCC Developerにもそんな機能ありませんか?
(1)構造体自体のメモリもmallocしているので、ここも重要です。
まぁ、fopenもFILE構造体のポインタを返しますが中で何をしているか意識せずに使えますよね?
こういう設計が隠蔽しているモジュール設計って事になります。

(2)grepがあります。BCC DeveloperだとCTRL+Gで呼び出せます。

Re: 引数のある関数

Posted: 2011年9月21日(水) 23:09
by 隠蔽
これを最後に立ち退きますので教えてくださいまし

BCCに既存のソースを読ませることってできますか?
もしかしてソースファイルを一つ一つコピーしなくてはならないのでしょうか?
また、grepとはどういうことでしょうか?
CTRL+GとはctrlキーとGキーを同時に押せば呼び出し元が分かるということでしょうか?

Re: 引数のある関数

Posted: 2011年9月21日(水) 23:24
by softya(ソフト屋)
隠蔽 さんが書きました:これを最後に立ち退きますので教えてくださいまし

(1)BCCに既存のソースを読ませることってできますか?
もしかしてソースファイルを一つ一つコピーしなくてはならないのでしょうか?

(2)また、grepとはどういうことでしょうか?
CTRL+GとはctrlキーとGキーを同時に押せば呼び出し元が分かるということでしょうか?
まぁ、最後と宣言しなくて良いんですけどね。
絶対次の疑問でが出てきますよ。

(1)プロジェクトを作ったら、
プロジェクトメニューで「プロジェクトに追加」でファイルを追加すれば良いだけです。

(2)[CTRL+G]はプログラマ界だけではなく、Windowsユーザーの間ではごく一般的な書き方です。
CTRLとGを同時に押すことで、CTRLはそもそも同時に押すためのキーです。
「コントロールキー - Wikipedia」
http://ja.wikipedia.org/wiki/%E3%82%B3% ... D%E3%83%BC

これを押すとBCC devlpoerではgerp検索メニューが開きます。これは全ファイルで文字列を検索するためのものです。
ファイル内検索は、CTRL+Fです。覚えておいてください。

Re: 引数のある関数

Posted: 2011年9月22日(木) 00:12
by 隠蔽
ありがとうございました
今、頭回らなくて言葉がないのですが
ツールの使い方まで勉強になりました
本当にありがとうございました
初心者な無知ですので多分、またお世話になるかもしれませんが
その時はよろしくお願いします すいません