ダメージ計算関数のテストをしてみたんですが、実行結果がおかしかったのデバックビルドをしたら、変数damage_seed(ダメージ計算の素となる値)がスクリーンショットの通り、おかしな値になっていました。
どこが問題なのか教えてください。
実行環境は、Visual Studio Community 2015です。
すごく初歩的な部分なんですが、よろしくお願いします。
int damage(int hit_probability, int critical_probability, int attack_level, int attack, int defence) {
/*
第1引数:攻撃のヒット率
第2引数:クリティカル率
第3引数:攻撃する人のレベル
第4引数:攻撃する人の攻撃力
第5引数:攻撃される人の守備力
*/
int damage_seed = attack - defence + random(attack_level, 0);
if (damage_seed <= 0 && judgement(50)) damage_seed = 1;
else damage_seed = 0;
if (!judgement(hit_probability)) damage = 0;
else if (judgement(critical_probability)) return static_cast<int>(((damage_seed)* 3 >> 2) + (1 >> 2));
else return damage_seed;
}
int main(void) {
int hp = 150;
hp -= damage(100, 10, 15, 155, 100);
std::cout << hp << std::endl;
}
他にも攻撃が当たるかやクリティカルが発生するかを判定するjudgement関数(bool型/引数:確率)と、乱数を返すrandom関数(int型/第1引数:乱数の最大値 第2引数:乱数の最小値)が存在しますが、そこには問題はなかったので省略しました。
No.2ベストアンサー
- 回答日時:
#1 の最後で指摘してされている点はどちらもエラーですな. ポインタ変数に 0 を代入するのは OK だけど, 関数名から変換されたポインタ値に代入するのはさすがにアウト. あと, 値を返す (つまり返り値の型が void でない) 関数は, main を除いて返り値を伴う return の実行が必須 (main だけは「return を実行しなかったら関数の最後に return 0; という文があるものとみなす」ことになっている).
以下おまけ:
まず, 「judgement」は関数名としてどうなんだろうか. 判定して bool値を返すのはいいけど, この名前から「どういうときに true を返してどういうときに false を返すのか」は読み取れないねぇ. この手の「ひどい名前」は有名なソフトウェアでも見かけることがある (そしてときどきバグが混入している) んだけど, やっぱり気を付けた方がいいと思うな.
それから
return static_cast<int>(((damage_seed)* 3 >> 2) + (1 >> 2));
の部分は
・damage_seed になぜ括弧をつけているのか
・1>>2 の結果は 0 だから加算の意味がない
・右辺はそもそも int なので static_cast が完全に余計
と, 無駄だらけ. ついでにいうとこの計算結果が damage_seed より小さいことに気づいてる?
damage = 0部分は、前の関数名の時にあった変数が残ってただけです。すいません。
static_castの部分はクリティカルヒット時のダメージ計算を行う部分なんですが、出てくる値に問題があったので変えました。
damage_seedが括弧で囲まれてるのはミスです。すいません。
そして原因は#1の方へのお礼のところにも書きました通り、3行目のelse文でした。
ありがとうございました。
No.1
- 回答日時:
>スクリーンショットの通り、おかしな値になっていました。
それを確認したのは、どの位置にブレークポイント設定した時ですか?
>int damage_seed = attack - defence + random(attack_level, 0);
の行であれば、後に書かれた計算式の処理前なので不定値が入っているのは正常です。
-858993460を16進数にすると0xCCCCCCCCなので…VC系のデバッグビルド時の未初期化ローカル変数としては正常な値でしょう。
# VCのデバッグビルドでは未初期化のローカル変数は0xCCで埋められます。
# よく文字列を表示してみたら最後に”フフフフフフフフ”って続くんですけどなんでしょう?とか書かれることがありますが。
# 「VC デバッグビルド 0xCC」辺りで検索して見てくださいな。
# リリースビルドだと本当に不定値が入っています。実行するたびに値が変わる可能性が高いですね。
んで…いろいろ端折っているのかも知れませんが、上記のdamage()にはおかしいところがあります。
インデントが見にくいので整形すると……
>int damage(int hit_probability, int critical_probability, int attack_level, int attack, int defence) {
> /*
> 略
> */
> int damage_seed = attack - defence + random(attack_level, 0);
> if (damage_seed <= 0 && judgement(50))
> damage_seed = 1;
> else
> damage_seed = 0;
>
> if (!judgement(hit_probability))
> damage = 0;
> else if (judgement(critical_probability))
> return static_cast<int>(((damage_seed)* 3 >> 2) + (1 >> 2));
> else
> return damage_seed;
>}
if (!judgement(hit_probability))
damage = 0;
で、関数ポインタに0を代入(?)しています。
ビルド通るんですか?
で、この条件以外ではreturnで値を返却していますが、このルートに入ると戻り値なしで関数抜けます。
# ビルド時にエラーになっていませんかね?
damage = 0
ここはreturn 0です。
元の関数の名前がdamage_calcで、その中にdamageっていう変数があったのがそのままになってました。すいません。
あと、処理の3行目のelse文が原因で、damage_seedが0にされてました。
スクリーンショットの件は、ブレークポイントの位置を間違えていたことが原因でした。
ありがとうございました。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・街中で見かけて「グッときた人」の思い出
- ・「一気に最後まで読んだ」本、教えて下さい!
- ・幼稚園時代「何組」でしたか?
- ・激凹みから立ち直る方法
- ・1つだけ過去を変えられるとしたら?
- ・【あるあるbot連動企画】あるあるbotに投稿したけど採用されなかったあるある募集
- ・【あるあるbot連動企画】フォロワー20万人のアカウントであなたのあるあるを披露してみませんか?
- ・映画のエンドロール観る派?観ない派?
- ・海外旅行から帰ってきたら、まず何を食べる?
- ・誕生日にもらった意外なもの
- ・天使と悪魔選手権
- ・ちょっと先の未来クイズ第2問
- ・【大喜利】【投稿~9/7】 ロボットの住む世界で流行ってる罰ゲームとは?
- ・推しミネラルウォーターはありますか?
- ・都道府県穴埋めゲーム
- ・この人頭いいなと思ったエピソード
- ・準・究極の選択
- ・ゆるやかでぃべーと タイムマシンを破壊すべきか。
- ・歩いた自慢大会
- ・許せない心理テスト
- ・字面がカッコいい英単語
- ・これ何て呼びますか Part2
- ・人生で一番思い出に残ってる靴
- ・ゆるやかでぃべーと すべての高校生はアルバイトをするべきだ。
- ・初めて自分の家と他人の家が違う、と意識した時
- ・単二電池
- ・チョコミントアイス
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
C言語での引数の省略方法
-
「指定されたキャストは有効で...
-
複数桁10進数の*桁目だけを抽出...
-
【C++】関数ポインタの使い方
-
if と配列の組み合わせ
-
#define _CRT_SECURE_NO_WARNIN...
-
未解決の外部シンボル _printf...
-
C++ の map についてです
-
read関数をノンブロッキングで...
-
C言語です。
-
cinの区切り文字の書き方
-
C言語でlookupのような関数って?
-
深さ優先探索について・・・
-
整数データの配列から同じ値の...
-
式は定数値が必要です」という...
-
(int *)の意味
-
int16_t の _t は何?
-
Win32APIで作るコンボボックス...
-
mfcの画像表示で、bmp表示がよ...
-
CygwinでSTLの勉強をしています...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
「指定されたキャストは有効で...
-
C言語での引数の省略方法
-
#define _CRT_SECURE_NO_WARNIN...
-
AtCoderABC135の問題Cについて
-
C言語 エラーの原因がわからな...
-
複数桁10進数の*桁目だけを抽出...
-
【C++】関数ポインタの使い方
-
実数の整数部,小数部の取得
-
ラップ関数とはどんなものですか?
-
if と配列の組み合わせ
-
return 1L
-
read関数をノンブロッキングで...
-
(int *)の意味
-
std::set<int> で、ある値が何...
-
Win32APIで作るコンボボックス...
-
C++でvectorにテキストファイル...
-
「{ } で囲むだけ」は正しい?
-
足して100になるような乱数のア...
-
Arduinoのプログラムにエラーが...
-
課題でつまってます・・・
おすすめ情報