ページ 11

思い通りに動いてくれません…

Posted: 2015年11月17日(火) 17:50
by 幻想
部活でプログラミングしているのですが、とても困っています。
windows7
Visual Studio 2010 Professional
DXライブラリを使用
プログラミング歴 1年程度
です。
下記が書いたプログラムです。

Scene.h

コード:

#pragma once

enum{
        sMenu,
        sQ1,
        sQ2,
        sQ3,
};

static int sFlag;
static int keyZflag;
Menu.h

コード:

#pragma once

void Menu();
void Q1();
void Q2();
void Q3();
main.cpp

コード:

#include"DxLib.h"
#include"Scene.h"
#include"Menu.h"

int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int){

     DxLib_Init(),
     ChangeWindowMode(TRUE),
     SetDrawScreen(DX_SCREEN_BACK);

     while(ScreenFlip()==0 && ProcessMessage()==0 && ClearDrawScreen()==0 && CheckHitKey(KEY_INPUT_ESCAPE)==0){

     switch(sFlag){
     case sMenu:
           Menu();
           break;
     case sQ1:
           Q1();
           break;
     case sQ2:
           Q2();
           break;
     case sQ3:
           Q3();
           break;
     default:
           break;
     }

     DxLib_End();
     return 0;
}
Menu.cpp

コード:

#include"DxLib.h"
#include"Scene.h"
#include"Menu.h"

void Menu(){
      DrawString(0,0,"Menu",GetColor(255,255,255));
      if(CheckHitKey(KEY_INPUT_Z)==1){
           if(keyZflag==0){
                sFlag=sQ1;
                keyZflag=1;
           }
      }else{
            keyZflag=0;
      }
}
Q.cpp

コード:

#include"DxLib.h"
#include"Scene.h"
#include"Menu.h"

void Q1(){
      DrawString(0,20,"Q1",GetColor(255,255,255));
      if(CheckHitKey(KEY_INPUT_Z)==1){
           if(keyZflag==0){
                sFlag=sQ2;
                keyZflag=1;
           }
      }else{
           keyZflag=0;
      }
}

void Q2(){
      DrawString(0,20,"Q2",GetColor(255,255,255));
      if(CheckHitKey(KEY_INPUT_Z)==1){
           if(keyZflag==0){
                sFlag=sQ3;
                keyZflag=1;
           }
      }else{
           keyZflag=0;
      }
}

void Q3(){
      DrawString(0,20,"Q3",GetColor(255,255,255));
      if(CheckHitKey(KEY_INPUT_Z)==1){
           if(keyZflag==0){
                sFlag=sMenu;
                keyZflag=1;
           }
      }else{
           keyZflag=0;
      }
}
これを実行してみると、まずZを押してもQ1と表示されません。
しかし、ブレークポイントなどを使用して調べたところ、
Menu関数でsQ1の代入はされているのに、
次のフレームでcase sQ1に行かないのです。
何が起こっているのでしょうか?
1週間程度考えましたが、全く分かりませんでした…
一緒に考えて頂けると嬉しいです。宜しくお願いします。

Re: 思い通りに動いてくれません…

Posted: 2015年11月17日(火) 18:04
by みけCAT
sFlagはstaticを付けて宣言されているため、WinMain関数(main.cpp)から見えるsFlagとMenu関数(Menu.cpp)から見えるsFlagsは別物です。
従って、Menu関数でsFlagを書き換えてもWinMain関数には反映されません。
対症療法としては、Scene.hのsFlagの宣言で使われているstaticをexternに変え、
main.cppでint型のグローバル変数sFlagをstaticを付けずに定義するといいでしょう。
keyZflagについても同様です。

Re: 思い通りに動いてくれません…

Posted: 2015年11月17日(火) 19:19
by 幻想
Scene.hで
extern int sFlag;
main.cppで
int sFlag;
としてみたところ、以下のようなエラーが出ました。

error LNK1120: 外部参照2が未解決です。
error LNK2001: 外部シンボル""int keyZflag"(?keyZflag@@3HA)"は未解決です。 Menu.obj
error LNK2001: 外部シンボル""int keyZflag"(?keyZflag@@3HA)"は未解決です。 Q.obj
error LNK2001: 外部シンボル""int sFlag"(?sFlag@@3HA)"は未解決です。 Menu.obj
error LNK2019: 未解決の外部シンボル"int sFlag"(?sFlag@@3HA)が関数"void__cdecl Q1(void)" (?Q1@@YAXXZ)で参照されました。Q.obj

externの使い方についても調べて、他の書き方も試してみましたが、やはりエラーが出てしまいます。

Re: 思い通りに動いてくれません…

Posted: 2015年11月17日(火) 20:20
by softya(ソフト屋)
ローカル変数とグローバル変数の定義の仕方の違いは理解していますか?
main.cppでローカル変数として定義している疑いがあります。

Re: 思い通りに動いてくれません…

Posted: 2015年11月18日(水) 17:08
by 幻想
返信遅れてすみません。
ソフト屋さん、ありがとうございます。
確認してみたところ、定義が無限ループの外にあるだけで、
完全に関数の外に出ていた訳ではありませんでした。
私の認識が甘かったですね…
ありがとうございました!