main関数の記述を関数に分けたらプログラムが動かなくなった

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
dast
記事: 41
登録日時: 13年前

main関数の記述を関数に分けたらプログラムが動かなくなった

#1

投稿記事 by dast » 13年前

こんにちは。プログラムを組んでいてmain関数が長くなってきたと感じたので一部の記述を別の関数に分けてデバックしてみたらビルドには成功したのですが、デバックの段階で「Run-Time Check Failure #3 - The variable 'time1' is being used without being initialized.」と表示されてプログラムが動きません。このプログラムを関数に分けた状態で動かすにはどうしたらいいでしょうか?ちなみに関数にする前は正常に動いていました。

改変前のソース

コード:

#include "DxLib.h"
#include <math.h>
 
#define g 9.8067//定e数?:重d力I加A速Ê度x
#define e 0.85//反?発-係W数?
#define y_max 2.000//定e数?
#define max_x 640//玉EのI移U動R範I囲I:F右E端[
#define min_x 0//玉EのI移U動R範I囲I:F左÷端[
#define max_y 480//玉EのI移U動R範I囲I:F床‹(iた?だ?しƒÊ計v算Z途r中?でAはI天V井a)j
#define min_y 0//玉EのI移U動R範I囲I:F天V井a(iた?だ?しƒÊ計v算Z途r中?でAはI床‹)j

//#define maxy 400.000//玉EのI軌O道1のI最A高?点_

typedef struct{
	int x,y,image;
	double xsp,at,maxy;//x方u向uのIスXピsー[ドh,当?た?りe判â定eのI半?径a,現â在YのI軌O道1のI最A高?点_
}TamaPara_t;
TamaPara_t TP;


 
int i;//forル?ー[プv用p変I数?

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow ){
        ChangeWindowMode( TRUE ) ;          // ウEイCン?ドhウEモ?ー[ドhにE変I更X
        if( DxLib_Init() == -1 ) return -1; //DXラ?イCブuラ?リ?初?期u化â エLラ~ー‹がa起Nきáた?らc終I了1 
 
        int x=640,y=0,time1,time2,flag=0,q=0;
        double t, v0, sy, ssy, zmaxy, m=1.000;//経o過s時?間O, 初?速Ê度x, 発-射E地n点_のIy座A標W, 床‹をd跳ƒÊねEた?時?のI発-射E地n点_のIy座A標W, 玉EのI飛oびN上aがaるe高?さ3, 玉EのI向uきá上a下o判â定e
        char Key[256];
 
        SetDrawScreen( DX_SCREEN_BACK ) ;//描`画a先aをd裏?画a面EにE設Y定e
 
        TP.image=LoadGraph("img/tama.png");
		TP.at=5;//玉EのI当?た?りe判â定eのI設Y定e
		TP.xsp=-4.000;//x方u向uのIスXピsー[ドh
		TP.maxy=600.00;//現â在YのI軌O道1のI最A高?点_のI初?期u化â
                                
        while(1){
                ClearDrawScreen();//裏?画a面EのIデfー[タ^をd全SてA削i除?
                GetHitKeyStateAll( Key ) ;           // すEべ~てAのIキLー[のI状o態Oをd得?るe
                if( ProcessMessage() == -1 ) break ; //異U常iがaおNきáた?らc終I了1
 
                if( flag==0 || flag==2 ){ //床‹のI当?た?りe判â定e1
                        time1 = GetNowCount();           //time1にEエGン?タ^ー[がa押?さ3れeた?時?のI時?間Oをd格i納[
						sy=y;
						if(flag==0){
							ssy=y;
						}
						zmaxy=TP.maxy-ssy;
                        flag=1;                          //飛oびN上aがaりeフtラ?グOをd立˜てAるe。B
                }
				else if(flag==1){
                        time2 = GetNowCount() ;                  // 現â在Y経o過s時?間Oをd得?るe
                        t = (double)(time2 - time1) / 1000.000;  // ミ~リ?秒bをd秒bにE変I換EしƒÊてA、AエGン?タ^ー[がa押?さ3れeてAかcらcのI経o過s時?間Oをd計v算Z
						/*if(m==1.000){*/
							v0 = sqrt ( 2.000 * g * y_max);
						/*}
						else*/ if(m==-1.000){
							v0 = v0-g*t;
						}
						for(i=0;i<q;i++){
							v0 *=e;
						}
                        y = sy+(m*v0 * t - 0.500 * g * t * t ) * zmaxy / y_max;//yのI計v算Z						
						x=(x+TP.xsp);//xのI計v算Z						
				
						if(y<(min_y+TP.at)){//床‹のI当?た?りe判â定e2
							y=min_y+TP.at;
							m=1.000;
							q+=1;
                            flag=0;// 画a面E外OにE来?るeとA、A飛oびN上aがaりeフtラ?グOをd戻sすE
						}
						else if(y>(max_y-TP.at)){//天V井aのI当?た?りe判â定e
							y=max_y-TP.at;
							m=-1.000;
							flag=2;
						}
						if(x<(min_x+TP.at)){//左÷端[のI当?た?りe判â定e&処?理?
							x=min_x+TP.at+1;
							TP.xsp*=(-1);
						}
						else if(x>(max_x-TP.at)){//右E端[のI当?た?りe判â定e&処?理?
							x=max_x-1-TP.at;
							TP.xsp*=(-1);
						}
						TP.y=(int)(480-y);//玉EのIy座A標WのI更X新V
						TP.x=(int)(x);//玉EのIx座A標WのI更X新V
                }

				DrawRotaGraph( TP.x , TP.y ,1.0,0.0, TP.image , TRUE );//画a像?をd描`画a
				DrawFormatString( 0, 0, GetColor(255,255,255), "%d",TP.y); // x,0 のI位E置uにE白?でA ?! をd描`画a
				DrawFormatString( 0, 20, GetColor(255,255,255), "%d",y); // x,0 のI位E置uにE白?でA ?! をd描`画a
				DrawFormatString( 0, 40, GetColor(255,255,255), "%d",flag); // x,0 のI位E置uにE白?でA ?! をd描`画a
				DrawFormatString( 0, 60, GetColor(255,255,255), "%d",q); // x,0 のI位E置uにE白?でA ?! をd描`画a
        
                if( Key[ KEY_INPUT_ESCAPE ]  == 1 ) break;   //Escボタ^ン?がa押?さ3れeた?らcブuレ?イCクN
 
                ScreenFlip() ;                               //裏?画a面Eデfー[タ^をd表\uinput2画a面EへO反?映f
        }
        DxLib_End() ;                                    // DcXwラ?イCブuラ?リ?使g用pのI終I了1処?理?
        return 0 ;                                       // ソ\uinput2フtトgのI終I了1
}

_
改編後のソース

コード:

#include "DxLib.h"
#include <math.h>
 
#define g 9.8067//定e数?:重d力I加A速Ê度x
#define e 0.85//反?発-係W数?
#define y_max 2.000//定e数?
#define max_x 640//玉EのI移U動R範I囲I:F右E端[
#define min_x 0//玉EのI移U動R範I囲I:F左÷端[
#define max_y 480//玉EのI移U動R範I囲I:F床‹(iた?だ?しƒÊ計v算Z途r中?でAはI天V井a)j
#define min_y 0//玉EのI移U動R範I囲I:F天V井a(iた?だ?しƒÊ計v算Z途r中?でAはI床‹)j

//#define maxy 400.000//玉EのI軌O道1のI最A高?点_


 
int i;//forル?ー[プv用p変I数?(使g用p関O数?:F全SてA)
int x=640,y=0,flag=0,q=0;//(使g用p関O数?:FTamaRifAndMove())
double m=1.000;//玉EのI向uきá上a下o判â定e(使g用p関O数?:FTamaRifAndMove())

typedef struct{
	int x,y,image;
	double xsp,at,maxy;//x方u向uのIスXピsー[ドh,当?た?りe判â定eのI半?径a,現â在YのI軌O道1のI最A高?点_
}TamaPara_t;
TamaPara_t TP;

void TamaRifAndMove(){
	int time1,time2;
	double t, v0, sy, ssy, zmaxy;//経o過s時?間O, 初?速Ê度x, 発-射E地n点_のIy座A標W, 床‹をd跳ƒÊねEた?時?のI発-射E地n点_のIy座A標W, 玉EのI飛oびN上aがaるe高?さ3
	if( flag==0 || flag==2 ){ //床‹のI当?た?りe判â定e1
		time1 = GetNowCount();           //time1にEエGン?タ^ー[がa押?さ3れeた?時?のI時?間Oをd格i納[
		sy=y;
		if(flag==0){
			ssy=y;
		}
		zmaxy=TP.maxy-ssy;
		flag=1;                          //飛oびN上aがaりeフtラ?グOをd立˜てAるe。B
	}
	else if(flag==1){
		time2 = GetNowCount() ;                  // 現â在Y経o過s時?間Oをd得?るe
		t = (double)(time2 - time1) / 1000.000;  // ミ~リ?秒bをd秒bにE変I換EしƒÊてA、AエGン?タ^ー[がa押?さ3れeてAかcらcのI経o過s時?間Oをd計v算Z
		v0 = sqrt ( 2.000 * g * y_max);
		if(m==-1.000){
			v0 = v0-g*t;
		}
		for(i=0;i<q;i++){
			v0 *=e;
		}
		y = sy+(m*v0 * t - 0.500 * g * t * t ) * zmaxy / y_max;//yのI計v算Z
		x=(x+TP.xsp);//xのI計v算Z
		if(y<(min_y+TP.at)){//床‹のI当?た?りe判â定e2
			y=min_y+TP.at;
			m=1.000;
			q+=1;
			flag=0;// 画a面E外OにE来?るeとA、A飛oびN上aがaりeフtラ?グOをd戻sすE
		}
		else if(y>(max_y-TP.at)){//天V井aのI当?た?りe判â定e
			y=max_y-TP.at;
			m=-1.000;
			flag=2;
		}
		if(x<(min_x+TP.at)){//左÷端[のI当?た?りe判â定e&処?理?
			x=min_x+TP.at+1;
			TP.xsp*=(-1);
		}
		else if(x>(max_x-TP.at)){//右E端[のI当?た?りe判â定e&処?理?
			x=max_x-1-TP.at;
			TP.xsp*=(-1);
		}
		TP.y=(int)(480-y);//玉EのIy座A標WのI更X新V
		TP.x=(int)(x);//玉EのIx座A標WのI更X新V
	}
}

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow ){
        ChangeWindowMode( TRUE ) ;          // ウEイCン?ドhウEモ?ー[ドhにE変I更X
        if( DxLib_Init() == -1 ) return -1; //DXラ?イCブuラ?リ?初?期u化â エLラ~ー‹がa起Nきáた?らc終I了1 
        
        char Key[256];
 
        SetDrawScreen( DX_SCREEN_BACK ) ;//描`画a先aをd裏?画a面EにE設Y定e
 
        TP.image=LoadGraph("img/tama.png");
		TP.at=5;//玉EのI当?た?りe判â定eのI設Y定e
		TP.xsp=-4.000;//x方u向uのIスXピsー[ドh
		TP.maxy=600.00;//現â在YのI軌O道1のI最A高?点_のI初?期u化â
                                
        while(1){
                ClearDrawScreen();//裏?画a面EのIデfー[タ^をd全SてA削i除?
                GetHitKeyStateAll( Key ) ;           // すEべ~てAのIキLー[のI状o態Oをd得?るe
                if( ProcessMessage() == -1 ) break ; //異U常iがaおNきáた?らc終I了1
 //こ

dast
記事: 41
登録日時: 13年前

Re: main関数の記述を関数に分けたらプログラムが動かなくなった

#2

投稿記事 by dast » 13年前

すみません、コードの部分が文字化けしてしまったようなのでもう一度送ります
改変前

コード:

#include "DxLib.h"
#include <math.h>
 
#define g 9.8067//定数:重力加速度
#define e 0.85//反発係数
#define y_max 2.000//定数
#define max_x 640//玉の移動範囲:右端
#define min_x 0//玉の移動範囲:左端
#define max_y 480//玉の移動範囲:床(ただし計算途中では天井)
#define min_y 0//玉の移動範囲:天井(ただし計算途中では床)

//#define maxy 400.000//玉の軌道の最高点

typedef struct{
	int x,y,image;
	double xsp,at,maxy;//x方向のスピード,当たり判定の半径,現在の軌道の最高点
}TamaPara_t;
TamaPara_t TP;


 
int i;//forループ用変数

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow ){
        ChangeWindowMode( TRUE ) ;          // ウインドウモードに変更
        if( DxLib_Init() == -1 ) return -1; //DXライブラリ初期化 エラーが起きたら終了 
 
        int x=640,y=0,time1,time2,flag=0,q=0;
        double t, v0, sy, ssy, zmaxy, m=1.000;//経過時間, 初速度, 発射地点のy座標, 床を跳ねた時の発射地点のy座標, 玉の飛び上がる高さ, 玉の向き上下判定
        char Key[256];
 
        SetDrawScreen( DX_SCREEN_BACK ) ;//描画先を裏画面に設定
 
        TP.image=LoadGraph("img/tama.png");
		TP.at=5;//玉の当たり判定の設定
		TP.xsp=-4.000;//x方向のスピード
		TP.maxy=600.00;//現在の軌道の最高点の初期化
                                
        while(1){
                ClearDrawScreen();//裏画面のデータを全て削除
                GetHitKeyStateAll( Key ) ;           // すべてのキーの状態を得る
                if( ProcessMessage() == -1 ) break ; //異常がおきたら終了
 
                if( flag==0 || flag==2 ){ //床の当たり判定1
                        time1 = GetNowCount();           //time1にエンターが押された時の時間を格納
						sy=y;
						if(flag==0){
							ssy=y;
						}
						zmaxy=TP.maxy-ssy;
                        flag=1;                          //飛び上がりフラグを立てる。
                }
				else if(flag==1){
                        time2 = GetNowCount() ;                  // 現在経過時間を得る
                        t = (double)(time2 - time1) / 1000.000;  // ミリ秒を秒に変換して、エンターが押されてからの経過時間を計算
						/*if(m==1.000){*/
							v0 = sqrt ( 2.000 * g * y_max);
						/*}
						else*/ if(m==-1.000){
							v0 = v0-g*t;
						}
						for(i=0;i<q;i++){
							v0 *=e;
						}
                        y = sy+(m*v0 * t - 0.500 * g * t * t ) * zmaxy / y_max;//yの計算						
						x=(x+TP.xsp);//xの計算						
				
						if(y<(min_y+TP.at)){//床の当たり判定2
							y=min_y+TP.at;
							m=1.000;
							q+=1;
                            flag=0;// 画面外に来ると、飛び上がりフラグを戻す
						}
						else if(y>(max_y-TP.at)){//天井の当たり判定
							y=max_y-TP.at;
							m=-1.000;
							flag=2;
						}
						if(x<(min_x+TP.at)){//左端の当たり判定&処理
							x=min_x+TP.at+1;
							TP.xsp*=(-1);
						}
						else if(x>(max_x-TP.at)){//右端の当たり判定&処理
							x=max_x-1-TP.at;
							TP.xsp*=(-1);
						}
						TP.y=(int)(480-y);//玉のy座標の更新
						TP.x=(int)(x);//玉のx座標の更新
                }

				DrawRotaGraph( TP.x , TP.y ,1.0,0.0, TP.image , TRUE );//画像を描画
				DrawFormatString( 0, 0, GetColor(255,255,255), "%d",TP.y); // x,0 の位置に白で ?! を描画
				DrawFormatString( 0, 20, GetColor(255,255,255), "%d",y); // x,0 の位置に白で ?! を描画
				DrawFormatString( 0, 40, GetColor(255,255,255), "%d",flag); // x,0 の位置に白で ?! を描画
				DrawFormatString( 0, 60, GetColor(255,255,255), "%d",q); // x,0 の位置に白で ?! を描画
        
                if( Key[ KEY_INPUT_ESCAPE ]  == 1 ) break;   //Escボタンが押されたらブレイク
 
                ScreenFlip() ;                               //裏画面データを表画面へ反映
        }
        DxLib_End() ;                                    // DXライブラリ使用の終了処理
        return 0 ;                                       // ソフトの終了
}

改変後

コード:

#include "DxLib.h"
#include <math.h>
 
#define g 9.8067//定数:重力加速度
#define e 0.85//反発係数
#define y_max 2.000//定数
#define max_x 640//玉の移動範囲:右端
#define min_x 0//玉の移動範囲:左端
#define max_y 480//玉の移動範囲:床(ただし計算途中では天井)
#define min_y 0//玉の移動範囲:天井(ただし計算途中では床)

//#define maxy 400.000//玉の軌道の最高点


 
int i;//forループ用変数(使用関数:全て)
int x=640,y=0,flag=0,q=0;//(使用関数:TamaRifAndMove())
double m=1.000;//玉の向き上下判定(使用関数:TamaRifAndMove())

typedef struct{
	int x,y,image;
	double xsp,at,maxy;//x方向のスピード,当たり判定の半径,現在の軌道の最高点
}TamaPara_t;
TamaPara_t TP;

void TamaRifAndMove(){
	int time1,time2;
	double t, v0, sy, ssy, zmaxy;//経過時間, 初速度, 発射地点のy座標, 床を跳ねた時の発射地点のy座標, 玉の飛び上がる高さ
	if( flag==0 || flag==2 ){ //床の当たり判定1
		time1 = GetNowCount();           //time1にエンターが押された時の時間を格納
		sy=y;
		if(flag==0){
			ssy=y;
		}
		zmaxy=TP.maxy-ssy;
		flag=1;                          //飛び上がりフラグを立てる。
	}
	else if(flag==1){
		time2 = GetNowCount() ;                  // 現在経過時間を得る
		t = (double)(time2 - time1) / 1000.000;  // ミリ秒を秒に変換して、エンターが押されてからの経過時間を計算
		v0 = sqrt ( 2.000 * g * y_max);
		if(m==-1.000){
			v0 = v0-g*t;
		}
		for(i=0;i<q;i++){
			v0 *=e;
		}
		y = sy+(m*v0 * t - 0.500 * g * t * t ) * zmaxy / y_max;//yの計算
		x=(x+TP.xsp);//xの計算
		if(y<(min_y+TP.at)){//床の当たり判定2
			y=min_y+TP.at;
			m=1.000;
			q+=1;
			flag=0;// 画面外に来ると、飛び上がりフラグを戻す
		}
		else if(y>(max_y-TP.at)){//天井の当たり判定
			y=max_y-TP.at;
			m=-1.000;
			flag=2;
		}
		if(x<(min_x+TP.at)){//左端の当たり判定&処理
			x=min_x+TP.at+1;
			TP.xsp*=(-1);
		}
		else if(x>(max_x-TP.at)){//右端の当たり判定&処理
			x=max_x-1-TP.at;
			TP.xsp*=(-1);
		}
		TP.y=(int)(480-y);//玉のy座標の更新
		TP.x=(int)(x);//玉のx座標の更新
	}
}

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow ){
        ChangeWindowMode( TRUE ) ;          // ウインドウモードに変更
        if( DxLib_Init() == -1 ) return -1; //DXライブラリ初期化 エラーが起きたら終了 
        
        char Key[256];
 
        SetDrawScreen( DX_SCREEN_BACK ) ;//描画先を裏画面に設定
 
        TP.image=LoadGraph("img/tama.png");
		TP.at=5;//玉の当たり判定の設定
		TP.xsp=-4.000;//x方向のスピード
		TP.maxy=600.00;//現在の軌道の最高点の初期化
                                
        while(1){
                ClearDrawScreen();//裏画面のデータを全て削除
                GetHitKeyStateAll( Key ) ;           // すべてのキーの状態を得る
                if( ProcessMessage() == -1 ) break ; //異常がおきたら終了
 //ここから
				TamaRifAndMove();
//ここまで

				DrawRotaGraph( TP.x , TP.y ,1.0,0.0, TP.image , TRUE );//画像を描画
				DrawFormatString( 0, 0, GetColor(255,255,255), "%d",TP.y); // x,0 の位置に白で ?! を描画
				DrawFormatString( 0, 20, GetColor(255,255,255), "%d",y); // x,0 の位置に白で ?! を描画
				DrawFormatString( 0, 40, GetColor(255,255,255), "%d",flag); // x,0 の位置に白で ?! を描画
				DrawFormatString( 0, 60, GetColor(255,255,255), "%d",q); // x,0 の位置に白で ?! を描画
        
                if( Key[ KEY_INPUT_ESCAPE ]  == 1 ) break;   //Escボタンが押されたらブレイク
 
                ScreenFlip() ;                               //裏画面データを表画面へ反映
        }
        DxLib_End() ;                                    // DXライブラリ使用の終了処理
        return 0 ;                                       // ソフトの終了
}

Ryo

Re: main関数の記述を関数に分けたらプログラムが動かなくなった

#3

投稿記事 by Ryo » 13年前

「Run-Time Check Failure #3 - The variable 'time1' is being used without being initialized.」
これは、time1という変数が、初期化されていない(値を入れていない状態)で使用されることがありますという警告。

改変後のtime1,time2は、TamaRifAndMove(){}のローカル変数になっています。
関数のローカル変数は、関数が呼び出されたときに生成され、関数が終了するときに破棄されます。
つまり、TamaRifAndMove()が、呼び出されるたびに、新しいtime1とtime2が生成されます。
そのため、flag=0,2のときにtime1に値を入れたとしても、使うことなく破棄され、
flag=1のときに呼び出されたTamaRifAndMove()では、time1は初期化されていない不定の値になります。

dast
記事: 41
登録日時: 13年前

Re: main関数の記述を関数に分けたらプログラムが動かなくなった

#4

投稿記事 by dast » 13年前

ご指摘をいただいてTamaRifAndMove(){}のローカル変数を全て関数の外で宣言したらできました。ありがとうございます。

閉鎖

“C言語何でも質問掲示板” へ戻る