C言語 - 内部関数へポインタ引数を渡すのは間違いなのか

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
アバター
VANQUISH
記事: 5
登録日時: 11年前
住所: 日本
連絡を取る:

C言語 - 内部関数へポインタ引数を渡すのは間違いなのか

#1

投稿記事 by VANQUISH » 10年前

当掲示板に初めて書き込ませていただきます。よろしくお願いいたします。
C言語(C++)を使用してVCCでゲームの作成を行っている者です。
分からない点があるのでご質問させてください。

ある関数に引数でポインタを渡し、更にその内部に関数がありそこへもポインタを渡す状況があるのですが、
この場合関数宣言と引数の指定(具体的に)記述方法はどうなるのでしょうか。

ソースがかなり長いです。申し訳ありません。
コードの中でいうとWalkSubroutine関数のプロトタイプ宣言、WalkSubroutine関数定義部分の引数指定箇所が怪しいと思うのですが改変しても結果はコンパイルエラーでした。
およびInputInLines関数内でこのWalkSubroutineを呼び出しているのですが、ここの記述部分でコンパイラがコード警告(赤い波線)を出していてその内容が「"int"の引数は型"int *"のパラメータと互換性がありません」です。互換性とは一体何の事なのでしょうか。(・_・???
ポインタを使用した関数内で再び内部関数に関数のポインタ引数を渡す事自体が間違いなのでしょうか。

コード:

// last update 2014/12/29 18:52
//
//
//------------------------
/* コードマップ
bank $01	header
bank $02	blank
bank $03	basement - direct script
bank $04	WinMain
bank $05	function 1 - system lv.
bank $06	function 2 - automatic lv.
bank $07	function 3 - manual lv.
bank $08	function 4
bank $09	function 5
bank $0A	blank
*/
//*****************************************
//
//
//		bank $01 [ header ]
//
//
//*****************************************
// #include <windows.h>
#include "DxLib.h"	// DXライブラリ設定・定義ヘッダファイルをインクルード

/* 構造体メンバ構成 */
struct OBJECT {
	int c ;						// オブジェクト画像ハンドル番号
	int d ;						// オブジェクト前面方角情報
	int f[8] ;						// 当たり判定点(八箇所)
	int o ;						// 操作情報
	int s ;						// ステータス情報
	int x ;						// X座標値
	int y ;						// Y座標値
	int z ;						// 立体空間位置
	int wa ;						// 歩行スクリプトカウンタ
	char wc ;					// 歩行スクリプトメーター
} ;

/* プロトタイプ宣言 */
/* fnc 1 */
int RotateShift ( char , int , char ) ;																			// ローテートシフト関数
void PauseMode ( int *a , int color ) ;																			// ポーズモード分岐関数
/* fnc 2 */
void BgMapTileSet ( int bg[][16] , int hit[][16] , int hdl[] ) ;														// マップ構築関数
void ObjectGraph ( int hit[] , int x , int y , int d , int hdl[] , int c ) ;												// スプライトオブジェクト表示関数
void AllTimesGravitation ( int pointer[] , int fielder[][16] , int *y , int *st ) ;										// 重力加重関数
int CrashShocker ( int hitpoint[] , int bmarea[][16] , int a ) ;														// 衝突判定関数
/* fnc 3 */
void InputInLines ( int hit[] , int pnt[][16] , int *opr , int *dir , int *sta , int *x , int *inc , int *chr , char *cnt ) ;		// キー入力関数
void WalkSubroutine ( int hit[] , int pnt[][16] , char a , int *opr , int *dir , int *x , int *inc , int *chr , char *cnt ) ;	// 歩行処理関数


//*****************************************
//
//
//		bank $02 [ blank ]
//
//
//*****************************************








//*****************************************
//
//
//		bank $03 [ basement - direct script ]
//
//
//*****************************************

int Key[256] ;							// キーが押されているフレーム数を格納します

int InputKey () {							// キーの入力状態を更新します
	char tmpKey[256] ;
	GetHitKeyStateAll ( tmpKey ) ;
	for ( int i = 0 ; i < 256 ; i ++ ) {
		if ( tmpKey[i] != 0 ) {
			Key[i] ++ ;
		} else {
			Key[i] = 0 ;
		}
	}
	return 0 ;
}


//*****************************************
//
//
//		bank $04 [ WinMain ]
//
//
//*****************************************

int WINAPI WinMain ( HINSTANCE , HINSTANCE , LPSTR , int ) {																// Windowsアプリケーションメイン関数を定義
	ChangeWindowMode ( TRUE ) ;																						// ウインドウモードの指定を行う
	SetGraphMode ( 256 , 240 , 16 ) ;																						// アプリケーション画面サイズを指定
	SetWindowSizeExtendRate ( 2.0 ) ;																					// 画面を2倍に拡大
	DxLib_Init () ;																											// DXライブラリ初期化処理
	SetDrawScreen ( DX_SCREEN_BACK ) ;																				// 標準描画処理を行うスペースを裏面に設定
	SetFontSize ( 12 ) ;																									// 描画する文字列のフォントサイズを指定
	SetFontThickness ( 1 ) ;																								// 描画する文字列のフォントウェイトを指定
	ChangeFont ( "Meiryo UI" ) ;																							// 描画する文字列のフォントを変更する
	
	int SpriteHandle[12] ;																									// スプライトデータハンドル配列
	int BgHandle[100] ;																									// BGデータハンドル配列
	int Col ;																												// デバッグモードの文字羅列用の色格納変数
	LoadDivGraph ( "../../../c - Graphics/SPRITEDATA/rockman_00.png" , 12 , 6 , 2 , 32 , 32 , SpriteHandle ) ;					// LoadDivGraph関数を使いデータハンドルに画像データを代入。画像は自動分割され配列化される
	LoadDivGraph ( "../../../c - Graphics/BGDATA/bg_01.png" , 0x40 , 0x10 , 0x04 , 16 , 16 , BgHandle ) ;						// LoadDivGraph関数を使いデータハンドルに画像データを代入。画像は自動分割され配列化される
	Col = GetColor ( 255 , 255 , 255 ) ;																					// 白色の値を取得
	
	struct OBJECT main ;																								// 構造体変数の宣言
	
	main.x = 98 ;																											// キャラクターの座標値(X座標)
	main.y = 38 ;																											// キャラクターの座標値(Y座標)
	main.z = -1 ;																											// 未使用定義番号
	main.f[0] = 0 ;																										// キャラクターの床面判定基準値(Y座標)、天面判定基準値(Y座標)
	main.f[1] = 0 ;																										// キャラクターの前方判定Y座標値(下段)、キャラクターのオブジェクト接触判定Y座標値(下段)
	main.f[2] = 0 ;																										// キャラクターの前方判定Y座標値(中段)、キャラクターのオブジェクト接触判定Y座標値(中段)
	main.f[3] = 0 ;																										// キャラクターの前方判定Y座標値(上段)、キャラクターのオブジェクト接触判定Y座標値(上段)
	main.f[4] = 0 ;																										// キャラクターの前方判定基準値(X座標)
	main.f[5] = 0 ;																										// キャラクターの床面判定X座標値(前方)
	main.f[6] = 0 ;																										// キャラクターの床面判定X座標値(中央)、キャラクターのオブジェクト接触判定基準値(X座標)
	main.f[7] = 0 ;																										// キャラクターの床面判定X座標値(後方)
	main.c = 0 ;																											// キャラクター画像データハンドル制御
	main.d = 0 ;																											// キャラクターの向き情報
	main.s = 0 ;																											// キャラクターの基本ステータス情報
	main.o = 0 ;																											// キャラクターの操縦ステータス情報
	main.wa = 0 ;																										// キャラクターの歩行情報
	main.wc = 0x4A ;																										// キャラクターの歩行スクリプト整合定数(C言語では2進数表記ができません)
	
	int pause = 0 ;																										// ポーズモードスイッチ
	
	int BG_Array[15][16] = {																								// 背景(BG)グラフィック描画ハンドルの配列
		{ 0x00 , 0x09 , 0x00 , 0x09 , 0x00 , 0x09 , 0x00 , 0x09 , 0x00 , 0x09 , 0x00 , 0x09 , 0x00 , 0x09 , 0x00 , 0x23 } ,			// マップチップタイル構成(ステージの構築)
		{ 0x09 , 0x09 , 0x09 , 0x09 , 0x09 , 0x09 , 0x09 , 0x09 , 0x09 , 0x09 , 0x09 , 0x09 , 0x09 , 0x09 , 0x09 , 0x23 } ,
		{ 0x00 , 0x09 , 0x00 , 0x09 , 0x00 , 0x09 , 0x00 , 0x09 , 0x00 , 0x09 , 0x00 , 0x09 , 0x00 , 0x09 , 0x00 , 0x23 } ,
		{ 0x09 , 0x09 , 0x09 , 0x09 , 0x09 , 0x09 , 0x09 , 0x09 , 0x09 , 0x09 , 0x09 , 0x09 , 0x09 , 0x09 , 0x09 , 0x23 } ,
		{ 0x00 , 0x09 , 0x00 , 0x09 , 0x00 , 0x09 , 0x00 , 0x09 , 0x00 , 0x09 , 0x00 , 0x09 , 0x00 , 0x09 , 0x20 , 0x24 } ,
		{ 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x22 , 0x09 , 0x09 , 0x09 , 0x23 , 0x24 } ,
		{ 0x27 , 0x27 , 0x27 , 0x27 , 0x27 , 0x27 , 0x27 , 0x27 , 0x27 , 0x27 , 0x28 , 0x09 , 0x00 , 0x09 , 0x23 , 0x24 } ,
		{ 0x09 , 0x09 , 0x09 , 0x09 , 0x09 , 0x09 , 0x09 , 0x09 , 0x09 , 0x09 , 0x09 , 0x09 , 0x09 , 0x09 , 0x23 , 0x24 } ,
		{ 0x00 , 0x09 , 0x00 , 0x09 , 0x00 , 0x09 , 0x00 , 0x09 , 0x00 , 0x09 , 0x00 , 0x09 , 0x00 , 0x09 , 0x23 , 0x24 } ,
		{ 0x09 , 0x09 , 0x09 , 0x09 , 0x09 , 0x09 , 0x09 , 0x09 , 0x09 , 0x09 , 0x09 , 0x09 , 0x09 , 0x09 , 0x23 , 0x24 } ,
		{ 0x00 , 0x09 , 0x00 , 0x09 , 0x00 , 0x09 , 0x00 , 0x09 , 0x00 , 0x09 , 0x00 , 0x09 , 0x00 , 0x09 , 0x23 , 0x24 } ,
		{ 0x09 , 0x09 , 0x09 , 0x09 , 0x09 , 0x09 , 0x09 , 0x09 , 0x09 , 0x09 , 0x09 , 0x09 , 0x09 , 0x09 , 0x23 , 0x24 } ,
		{ 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x22 , 0x2F , 0x23 , 0x24 } ,
		{ 0x24 , 0x24 , 0x24 , 0x24 , 0x24 , 0x24 , 0x24 , 0x24 , 0x24 , 0x24 , 0x24 , 0x24 , 0x25 , 0x09 , 0x23 , 0x24 } ,
		{ 0x24 , 0x24 , 0x24 , 0x24 , 0x24 , 0x24 , 0x24 , 0x24 , 0x24 , 0x24 , 0x24 , 0x24 , 0x25 , 0x09 , 0x23 , 0x24 }
	} ;
	int BGHIT_Pointer[15][16] ;																							// マップチップの当たり判定用配列
	
	while ( ScreenFlip () == 0 && ProcessMessage () == 0 && ClearDrawScreen () == 0 && InputKey () == 0 ) {					// whileループ
		/* ここからメイン処理を記述します */
		
		PauseMode ( &pause , Col ) ;																						// ポーズモード分岐処理
		
		BgMapTileSet ( BG_Array , BGHIT_Pointer , BgHandle ) ;																// マップ構築処理
		ObjectGraph ( main.f , main.x , main.y , main.d , SpriteHandle , main.c ) ;												// スプライトオブジェクト処理
		AllTimesGravitation ( main.f , BGHIT_Pointer , &main.y , &main.s ) ;													// 重力加重処理
		
		InputInLines ( main.f , BGHIT_Pointer , &main.o , &main.d , &main.s , &main.x , &main.wa , &main.c , &main.wc ) ;			// キー入力処理
		
		/* ここまでメイン処理を記述します */
	}
	DxLib_End () ;																										// DXライブラリ終了処理
	return 0 ;																											// 必ず0を返してください
}


//*****************************************
//
//
//		bank $05 [ function 1 - system lv. ]
//
//
//*****************************************

/* ローテートシフト関数 */
int RotateShift ( char count , int repet , char judge )				// 引数は左から“ビットシフトする変数本体”、“シフト回数”、“シフト方向(RoR or RoL)[文字にLかRを指定]”
{
	int revise = 0 ;
	int falsive = 0 ;
	
	if ( judge == 'L' ) {											// judgeが2の時はRotate of Leftを行う
		for ( int i = 0 ; i < repet ; i ++ ) {							// repet回数だけ繰り返す文
			if ( count < 0 ) {										// カウンタ値が0以下(-128~-1、すなわち上位ビットが1の時)なら、
				revise = 1 ;										// 1をホールドする
			} else {												// それ以外なら
				revise = 0 ;										// 0をホールドする
			}
			count = count << 1 ;									// カウンタを左へビットシフト
			count = count + revise ;								// カウンタにホールドした整数を足す(擬似的なローテートシフトを行う)
		}
	} else if ( judge == 'R' ) {										// judgeが1の時はRotate of Rightを行う
		for ( int i = 0 ; i < repet ; i ++ ) {
			falsive = count % 2 ;
			if ( falsive != 0 ) {										// カウンタ値が2の倍数でなければ(最下位ビットが1なら)、
				revise = -128 ;									// -128をホールドする
			} else {												// それ以外なら
				revise = 0 ;										// 0をホールドする
			}
			count = count >> 1 ;									// カウンタを右へビットシフト
			count = count + revise ;								// カウンタにホールドした整数を足す(擬似的なローテートシフトを行う)
		}
	}
	return count ;												// カウンタを返します
}

/* ポーズモード分岐 */
void PauseMode ( int *a , int color ) 
{
	if ( Key[KEY_INPUT_PAUSE] == 1 ) {							// ポーズモードスイッチ
		*a = 1 ;													// ポーズモードフラグを立てる
	} else {
		// undefined
	}
	while ( *a == 1 && ProcessMessage () == 0 && InputKey () == 0 ) {
		
		DrawString ( 2 , 2 , "One Frame Viewing" , color ) ;			// ポーズモードである事を示す文字列を画面左上に表示する
		
		if ( Key[KEY_INPUT_PAUSE] == 1 ) {						// ポーズモードスイッチ
			*a = 0 ;												// ポーズモードフラグを降ろす
		} else if ( Key[KEY_INPUT_BACKSLASH] == 1 ) {			
			break ;												// LOOP脱出
		} else {
			// undefined
		}
	}
}


//*****************************************
//
//
//		bank $06 [ function 2 - automatic lv. ]
//
//
//*****************************************

/* マップ構築 */
void BgMapTileSet ( int bg[][16] , int hit[][16] , int hdl[] ) 
{
	for ( int i = 0 ; i < 15 ; i ++ ) {												// マップ構築を行う(マップチップ描画・マップ当たり判定の制定)
		for ( int j = 0 ; j < 16 ; j ++ ) {
			int k , l , m ;
			k = bg[i][j] ;
			l = j * 16 ;
			m = i * 16 ;
			DrawGraph ( l , m , hdl[k] , TRUE ) ;								// DrawGraph関数で指定された座標にマップチップ画像を描画
			
			if ( k >= 0x00 && k <= 0x1F ) {									// 当たり判定識別区分けを行う
				hit[i][j] = 0 ;													// 背景判定“空間”を指定
			} else if ( k >= 0x20 && k <= 0x3F ) {
				hit[i][j] = 1 ;													// 背景判定“壁”を指定
			} else {
				hit[i][j] = -1 ;												// 背景判定に例外値を指定
			}
		}
	}
}

/* スプライトオブジェクト */
void ObjectGraph ( int hit[] , int x , int y , int d , int hdl[] , int c ) 
{
	DrawGraph ( x , y , hdl[c] , TRUE ) ;										// オブジェクト描画
	
	*hit = y + 31 ;															// キャラクターの床面当たり判定Y座標値
	++hit ;
	*hit = y + 30 ;															// キャラクターの前面当たり判定Y座標値(下段)
	++hit ;
	*hit = y + 15 ;															// キャラクターの前面当たり判定Y座標値(中段)
	++hit ;
	*hit = y + 7 ;															// キャラクターの前面当たり判定Y座標値(上段)
	++hit ;
	if ( d == 1 ) {
		*hit = x + 25 ;														// キャラクターの前面当たり判定X座標値(右向き)
	} else if ( d == 2 ) {
		*hit = x + 7 ;														// キャラクターの前面当たり判定X座標値(左向き)
	}
	++hit ;
	*hit = x + 24 ;															// キャラクターの床面当たり判定X座標値(前方)
	++hit ;
	*hit = x + 17 ;															// キャラクターの床面当たり判定X座標値(中央)
	++hit ;
	*hit = x + 10 ;															// キャラクターの床面当たり判定X座	標値(後方)
}

/* 重力加重 */
void AllTimesGravitation ( int pointer[] , int fielder[][16] , int *y , int *st ) 
{
	int y1 = (*pointer + 1) / 16 ;												// Y座標、下に1ドットずれた位置のマップチップ番号を調べる
	for ( int i = 0 ; i < 5 ; i++ ) {												// 判定座標配列番号の操作
		++pointer ;
	}
	int x1 = *pointer / 16 ;													// X座標、現在位置のマップチップ番号を調べる
	++pointer ;
	int x2 = *pointer / 16 ;
	++pointer ;
	int x3 = *pointer / 16 ;
	if ( fielder[y1][x1] == 0 && fielder[y1][x2] == 0 && fielder[y1][x3] == 0 ) {		// 背景判定が空間の場合、
		*y = *y + 1 ;															// Y座標値を増やす (キャラクターを下方向へ移動させる)
		*st = 2 ;																// 空中滞空である識別値を代入する
	} else if ( fielder[y1][x1] == 1 || fielder[y1][x2] == 1 || fielder[y1][x3] == 1 ) {	// 背景判定が壁の場合、
		*st = 1 ;																// 地上待機である識別値を代入する
	}
}

/* 衝突判定関数 */
int CrashShocker ( int hitpoint[] , int bmarea[][16] , int a ) 
{
	hitpoint++ ;																					// 配列アドレスの操作
	int y1 = *hitpoint / 16 ;																		// Y座標、現在位置のマップチップ番号を調べる
	hitpoint++ ;																					// 配列アドレスの操作
	int y2 = *hitpoint / 16 ;																		// Y座標、現在位置のマップチップ番号を調べる
	hitpoint++ ;																					// 配列アドレスの操作
	int y3 = *hitpoint / 16 ;																		// Y座標、現在位置のマップチップ番号を調べる
	hitpoint++ ;																					// 配列アドレスの操作
	int x1 = (*hitpoint + a) / 16 ;																	// X座標、右に1ドットずれた位置のマップチップ番号を調べる
	if ( bmarea[y1][x1] == 0 && bmarea[y2][x1] == 0 && bmarea[y3][x1] == 0 ) {						// もし前進可能なら、
		return 0 ;																				// 0を返す
	} else if ( bmarea[y1][x1] == 1 || bmarea[y2][x1] == 1 || bmarea[y3][x1] == 1 ) {						// もし衝突判定なら、
		return 1 ;																				// 1を返す
	} else {																						// それ以外なら、
		return -1 ;																				// -1を返す
	}
}


//*****************************************
//
//
//		bank $07 [ function 3 - manual lv. ]
//
//
//*****************************************

/* キー入力 (各処理分岐関数) */
void InputInLines ( int hit[] , int pnt[][16] , int *opr , int *dir , int *sta , int *x , int *inc , int *chr , char *cnt ) 
{
	/* キー入力判断を行う */
	if ( Key[KEY_INPUT_RIGHT] > 0 ) {																	// 右キーが押されていたら、
		/* 処理 A */
		/* ステータス情報チェックを行う */
		if ( *sta == 1 ) {																				// 地上にいるなら、
			WalkSubroutine ( hit , pnt , 'R' , *opr , *dir , *x , *inc , *chr , *cnt ) ;								// 歩行処理を実行する (キー方向:R)
		} else if ( *sta == 2 ) {																		// 空中にいるなら、
			// 空力処理を実行する
		} else {																						// それ以外の場合は、
			// undefined
		}
	} else if ( Key[KEY_INPUT_LEFT] > 0 ) {																// 左キーが押されていたら、
		/* 処理 B */
		/* ステータス情報チェックを行う */
		if ( *sta == 1 ) {																				// 地上にいるなら、
			WalkSubroutine ( hit , pnt , 'L' , *opr , *dir , *x , *inc , *chr , *cnt ) ;								// 歩行処理を実行する (キー方向:L)
		} else if ( *sta == 2 ) {																		// 空中にいるなら、
			// 空力処理を実行する
		} else {																						// それ以外の場合は、
			// undefined
		}
	} else {																							// 左右キーが押されていなかったら、
		/* 処理 C */
		/* キャラクター動作情報をチェックする */
		if ( *opr == 1 ) {																				// 歩行状態なら、
			/* キャラクター方向情報をチェックする */
			if ( *dir == 1 ) {																			// 右向きなら、
				WalkSubroutine ( hit , pnt , 'T' , *opr , *dir , *x , *inc , *chr , *cnt ) ;									// 歩行処理を実行する (キー方向:T)
			} else if ( *dir == 2 ) {																		// 左向きなら、
				WalkSubroutine ( hit , pnt , 'K' , *opr , *dir , *x , *inc , *chr , *cnt ) ;									// 歩行処理を実行する (キー方向:K)
			} else {																					// それ以外なら、
				// undefined
			}
		} else if ( *opr == 0 ) {																		// スタンバイ状態なら、
			// undefined
		} else {																						// それ以外なら、
			MessageBox (
				GetMainWindowHandle () ,
				" プレイヤーの動作情報値が異常です。 ",
				" プログラムエラー ",
				MB_OK | MB_ICONERROR ) ;															// プログラムエラーとする
		}
	}
	if ( Key[KEY_INPUT_UP] > 0 ) {																		// 上キーが押されていたら、
		/* 処理 E */
		
		
	} else if ( Key[KEY_INPUT_DOWN] > 0 ) {															// 下キーが押されていたら、
		/* 処理 F */
		
		
	} else {																							// 上下キーが押されていなかったら、
		/* 処理 G */
		
		
	}
	if ( Key[KEY_INPUT_Z] > 0 ) {																		// Aボタン(Zキー)が押されていたら、
		/* 処理 I */
		
		
	} else {																							// Aボタン(Zキー)が押されていなかったら、
		/* 処理 J */
		
		
	}
	if ( Key[KEY_INPUT_X] > 0 ) {																		// Bボタン(Xキー)が押されていたら、
		/* 処理 L */
		
		
	} else {																							// Bボタン(Xキー)が押されていなかったら、
		/* 処理 M */
		
		
	}
	if ( Key[KEY_INPUT_C] > 0 ) {																		// STARTボタン(Cキー)が押されていたら、
		/* 処理 O */
		
		
	} else {																							// STARTボタン(Cキー)が押されていなかったら、
		/* 処理 P */
		
		
	}
	if ( Key[KEY_INPUT_V] > 0 ) {																		// SELECTボタン(Vキー)が押されたら、
		/* 処理 R */
		
		
	} else {																							// SELECTボタン(Vキー)が押されていなかったら、
		/* 処理 S */
		
		
	}
	if ( Key[KEY_INPUT_S] > 0 ) {																		// 仮想Yボタン(Sキー)が押されたら、
		/* 処理 Y1 */
		
		
	} else {																							// 仮想Yボタン(Sキー)が押さていなかったら、
		/* 処理 Y2 */
		
		
	}
	if ( Key[KEY_INPUT_A] > 0 ) {																		// 仮想Xボタン(Aキー)が押されたら、
		/* 処理 X1 */
		
		
	} else {																							// 仮想Xボタン(Aキー)が押されていなかったら、
		/* 処理 X2 */
		
		
	}
	if ( Key[KEY_INPUT_Q] > 0 ) {																		// 仮想Lボタン(Qキー)が押されたら、
		/* 処理 V1 */
		
		
	} else {																							// 仮想Lボタン(Qキー)が押されなかったら、
		/* 処理 V2 */
		
		
	}
	if ( Key[KEY_INPUT_W] > 0 ) {																		// 仮想Rボタン(Wキー)が押されたら、
		/* 処理 U1 */
		
		
	} else {																							// 仮想Rボタン(Wキー)が押されなかったら、
		/* 処理 U2 */
		
		
	}
}

/* 歩行処理 */
void WalkSubroutine ( int hit[] , int pnt[][16] , char a , int *opr , int *dir , int *x , int *inc , int *chr , char *cnt ) 
{
	(*inc)++ ;																														// 歩行用カウンタをインクリメントする
	/* カウンタループ処理:歩行用カウンタをチェックする */
	if ( *inc == 35 ) {																													// カウンタ数値が35なら、
		*inc = 7 ;																													// 歩行用カウンタに7をセットする
	} else {																															// それ以外の数値なら、
		// undefined
	}
	/* キー方向をチェックする */
	if ( a == 'R' ) {																													// もしキー方向が"R"なら、
		*dir = 1 ;																													// キャラクター方向情報を右向きにする
		/* 歩行画像切り替え:歩行用カウンタをチェックする */
		if ( *inc <= 6 ) {																												// カウンタ数値が6以下(1~6)なら、
			*chr = 2 ;																												// キャラクターイメージハンドラを配列番号2へ変える
		} else if ( *inc <= 13 ) {																										// カウンタ数値が13以下(7~13)なら、
			*chr = 3 ;																												// キャラクターイメージハンドラを配列番号3へ変える
		} else if ( *inc <= 20 ) {																										// カウンタ数値が20以下(14~20)なら、
			*chr = 5 ;																												// キャラクターイメージハンドラを配列番号5へ変える
		} else if ( *inc <= 27 ) {																										// カウンタ数値が27以下(21~27)なら、
			*chr = 4 ;																												// キャラクターイメージハンドラを配列番号4へ変える
		} else if ( *inc <= 34 ) {																										// カウンタ数値が34以下(28~34)なら、
			*chr = 5 ;																												// キャラクターイメージハンドラを配列番号5へ変える
		} else {																														// それ以外の数値なら、
			MessageBox ( 
				GetMainWindowHandle () ,
				" 歩行制御カウンタが例外フローしました。 ",
				" プログラムエラー ",
				MB_OK | MB_ICONERROR ) ;																							// プログラムエラーとする
		}
		/* 右方面の障害物衝突判定を行う */
		if ( CrashShocker ( hit , pnt , 1 ) == 0 ) {																						// もし前進可能なら、
			/* 歩行中座標移動:歩行用カウンタをチェックする */
			if ( *inc <= 6 ) {																											// もしカウンタ数値が6以下(1~6)なら、
				/* 座標移動用メーターをチェックする */
				if ( *cnt == 0x4A ) {																									// メーター指数が0x4A(01001010)なら、
					(*x)++ ;																											// キャラクターX座標値をインクリメントする
				} else if ( *cnt == 0x29 || *cnt == 0x52 || *cnt == 0x49 || *cnt == 0x25 || *cnt == -108 || *cnt == -92 || *cnt == -110 ) {	// メーター指数が0x4A(01001010)以外なら、
					// undefined
				} else {																												// それ以外なら、
					MessageBox ( 
						GetMainWindowHandle () ,
						" 座標移動用のメーター指数が異常です。 ",
						" プログラムエラー ",
						MB_OK | MB_ICONERROR ) ;																					// プログラムエラーとする
				}
			} else if ( *inc <= 34 ) {																									// もしカウンタ数値が34以下(7~34)なら、
				/* 座標移動用メーターをチェックする */
				if ( *cnt == -108 || *cnt == -92 || *cnt == -110 ) {																		// メーター指数が-108、-92、-110なら、
					*x = *x + 2 ;																										// キャラクターX座標値を+2加算する
				} else if ( *cnt == 0x4A || *cnt == 0x29 || *cnt == 0x52 || *cnt == 0x49 || *cnt == 0x25 ) {									// メーター指数が0x4A、0x29、0x52、0x49、0x25なら、
					(*x)++ ;																											// キャラクターX座標値をインクリメントする
				} else {																												// それ以外なら、
					MessageBox ( 
						GetMainWindowHandle () ,
						" 座標移動用のメーター指数が異常です。 ",
						" プログラムエラー ",
						MB_OK | MB_ICONERROR ) ;																					// プログラムエラーとする
				}
			} else {																													// それ以外の数値なら、
				MessageBox ( 
					GetMainWindowHandle () ,
					" 歩行制御カウンタが例外フローしました。 ",
					" プログラムエラー ",
					MB_OK | MB_ICONERROR ) ;																						// プログラムエラーとする
			}
			*cnt = RotateShift ( *cnt , 1 , 'L' ) ;																						// 座標移動用メーターを1回ローテート左シフトする
		} else if ( CrashShocker ( hit , pnt , 1 ) == 1 ) {																					// もし衝突判定なら、
			*cnt = RotateShift ( *cnt , 1 , 'L' ) ;																						// 座標移動用メーターを1回ローテート左シフトする
		} else {																														// いずれにも当てはまらなければ、
			// undefined
		}
	} else if ( a == 'L' ) {																												// もしキー方向が"L"なら、
		*dir = 2 ;																													// キャラクター方向情報を左向きにする
		/* 歩行画像切り替え:歩行用カウンタをチェックする */
		if ( *inc <= 6 ) {																												// カウンタ数値が6以下(1~6)なら、
			*chr = 8 ;																												// キャラクターイメージハンドラを配列番号8へ変える
		} else if ( *inc <= 13 ) {																										// カウンタ数値が13以下(7~13)なら、
			*chr = 9 ;																												// キャラクターイメージハンドラを配列番号9へ変える
		} else if ( *inc <= 20 ) {																										// カウンタ数値が20以下(14~20)なら、
			*chr = 11 ;																												// キャラクターイメージハンドラを配列番号11へ変える
		} else if ( *inc <= 27 ) {																										// カウンタ数値が27以下(21~27)なら、
			*chr = 10 ;																												// キャラクターイメージハンドラを配列番号10へ変える
		} else if ( *inc <= 34 ) {																										// カウンタ数値が34以下(28~34)なら、
			*chr = 11 ;																												// キャラクターイメージハンドラを配列番号11へ変える
		} else {																														// それ以外の数値なら、
			MessageBox ( 
				GetMainWindowHandle () ,
				" 歩行制御カウンタが例外フローしました。 ",
				" プログラムエラー ",
				MB_OK | MB_ICONERROR ) ;																							// プログラムエラーとする
		}
		/* 左方面の障害物衝突判定を行う */
		if ( CrashShocker ( hit , pnt , -1 ) == 0 ) {																						// もし前進可能なら、
			/* 歩行中座標移動:歩行用カウンタをチェックする */
			if ( *inc <= 6 ) {																											// もしカウンタ数値が6以下(1~6)なら、
				/* 座標移動用メーターをチェックする */
				if ( *cnt == 0x4A ) {																									// メーター指数が0x4A(01001010)なら、
					(*x)-- ;																											// キャラクターX座標値をデクリメントする
				} else if ( *cnt == 0x29 || *cnt == 0x52 || *cnt == 0x49 || *cnt == 0x25 || *cnt == -108 || *cnt == -92 || *cnt == -110 ) {	// メーター指数が0x4A(01001010)以外なら、
					// undefined
				} else {																												// それ以外なら、
					MessageBox ( 
						GetMainWindowHandle () ,
						" 座標移動用のメーター指数が異常です。 ",
						" プログラムエラー ",
						MB_OK | MB_ICONERROR ) ;																					// プログラムエラーとする
				}
			} else if ( *inc <= 34 ) {																									// もしカウンタ数値が34以下(7~34)なら、
				/* 座標移動用メーターをチェックする */
				if ( *cnt == -108 || *cnt == -92 || *cnt == -110 ) {																		// メーター指数が-108、-92、-110なら、
					*x = *x - 2 ;																										// キャラクターX座標値を-2加算する
				} else if ( *cnt == 0x4A || *cnt == 0x29 || *cnt == 0x52 || *cnt == 0x49 || *cnt == 0x25 ) {									// メーター指数が0x4A、0x29、0x52、0x49、0x25なら、
					(*x)-- ;																											// キャラクターX座標値をデクリメントする
				} else {																												// それ以外なら、
					MessageBox ( 
						GetMainWindowHandle () ,
						" 座標移動用のメーター指数が異常です。 ",
						" プログラムエラー ",
						MB_OK | MB_ICONERROR ) ;																					// プログラムエラーとする
				}
			} else {																													// それ以外の数値なら、
				MessageBox ( 
					GetMainWindowHandle () ,
					" 歩行制御カウンタが例外フローしました。 ",
					" プログラムエラー ",
					MB_OK | MB_ICONERROR ) ;																						// プログラムエラーとする
			}
			*cnt = RotateShift ( *cnt , 1 , 'L' ) ;																						// 座標移動用メーターを1回ローテート左シフトする
		} else if ( CrashShocker ( hit , pnt , -1 ) == 1 ) {																				// もし衝突判定なら、
			*cnt = RotateShift ( *cnt , 1 , 'L' ) ;																						// 座標移動用メーターを1回ローテート左シフトする
		} else {																														// いずれにも当てはまらなければ、
			// undefined
		}
	} else if ( a == 'T' ) {																												// もしキー方向が"T"なら、
		*dir = 1 ;																													// キャラクター方向情報を右向きにする
		/* 歩行終了処理:歩行用カウンタをチェックする */
		if ( *inc <= 6 ) {																												// もしカウンタ数値が6以下(1~6)なら、
			*inc = 41 ;																												// 歩行用カウンタに41をセットする
		} else if ( *inc >= 7 && *inc <= 34 ) {																							// もしカウンタ数値が7以上かつ34以下なら、(elseではなく、純if文の可能性がある)
			*inc = 35 ;																												// 歩行用カウンタに35をセットする
		} else if ( *inc >= 36 && *inc <= 42 ) {																							// もしカウンタ数値が36以上かつ42以下なら、
			*chr = 2 ;																												// キャラクターイメージハンドラを配列番号2へ変える
			/* 座標移動用メーターをチェックする */
			if ( CrashShocker ( hit , pnt , 1 ) == 0 && *cnt == 0x4A || *cnt == 0x29 || *cnt == -92 || *cnt == -110 ) {						// メーター指数が0x4A、0x29、-92、-110なら、
				(*x)++ ;																												// キャラクターX座標値をインクリメントする
			} else {																													// それ以外なら、
				// undefined
			}
		} else {																														// それ以外の数値なら、
			MessageBox ( 
				GetMainWindowHandle () ,
				" 未定義命令にステートしました。(歩行処理) ",
				" プログラムエラー ",
				MB_OK | MB_ICONERROR ) ;																							// プログラムエラーとする
		}
		*cnt = RotateShift ( *cnt , 1 , 'L' ) ;																							// 座標移動用メーターを1回ローテート左シフトする
	} else if ( a == 'K' ) {																												// もしキー方向が"K"なら、
		*dir = 2 ;																													// キャラクター方向情報を左向きにする
		/* 歩行終了処理:歩行用カウンタをチェックする */
		if ( *inc <= 6 ) {																												// もしカウンタ数値が6以下(1~6)なら、
			*inc = 41 ;																												// 歩行用カウンタに41をセットする
		} else if ( *inc >= 7 && *inc <= 34 ) {																							// もしカウンタ数値が7以上かつ34以下なら、(elseではなく、純if文の可能性がある)
			*inc = 35 ;																												// 歩行用カウンタに35をセットする
		} else if ( *inc >= 36 && *inc <= 42 ) {																							// もしカウンタ数値が36以上かつ42以下なら、
			*chr = 2 ;																												// キャラクターイメージハンドラを配列番号2へ変える
			/* 座標移動用メーターをチェックする */
			if ( *cnt == 0x4A || *cnt == 0x29 || *cnt == -92 || *cnt == -110 ) {															// メーター指数が0x4A、0x29、-92、-110なら、
				(*x)-- ;																												// キャラクターX座標値をデクリメントする
			} else {																													// それ以外なら、
				// undefined
			}
		} else {																														// それ以外の数値なら、
			MessageBox ( 
				GetMainWindowHandle () ,
				" 未定義命令にステートしました。(歩行処理) ",
				" プログラムエラー ",
				MB_OK | MB_ICONERROR ) ;																							// プログラムエラーとする
		}
		*cnt = RotateShift ( *cnt , 1 , 'L' ) ;																							// 座標移動用メーターを1回ローテート左シフトする
	} else {																															// それ以外(例外値)なら、
		MessageBox ( 
			GetMainWindowHandle () ,
			" キー方向実引数が正しくありません。 ",
			" プログラムエラー ",
			MB_OK | MB_ICONERROR ) ;																								// プログラムエラーとする
	}
	/* 継続制御:歩行用カウンタをチェックする */
	if ( *inc <= 41 ) {																												// もしカウンタ数値が41以下なら、
		*opr = 1 ;																												// キャラクター動作情報を歩行状態にする
	} else if ( *inc == 42 ) {																										// もしカウンタ数値が42なら、
		*chr = 0 ;																												// キャラクターイメージハンドラを配列番号0へ変える
		*inc = 0 ;																												// 歩行用カウンタに0をセットする
		*opr = 0 ;																												// キャラクター動作情報をスタンバイ状態にする
	} else {																														// それ以外の数値なら、
		MessageBox ( 
			GetMainWindowHandle () ,
			" 歩行用カウンタが想定外領域に到達しました。 ",
			" プログラムエラー ",
			MB_OK | MB_ICONERROR ) ;																							// プログラムエラーとする
	}
}

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: C言語 - 内部関数へポインタ引数を渡すのは間違いなのか

#2

投稿記事 by みけCAT » 10年前

VANQUISH さんが書きました:ある関数に引数でポインタを渡し、更にその内部に関数がありそこへもポインタを渡す状況があるのですが、
この場合関数宣言と引数の指定(具体的に)記述方法はどうなるのでしょうか。
普通に必要なデータを渡せばいいと思います。
「ある関数の内部に関数が有り」というのはよくわからないですが、
C言語ならGCC拡張で関数の入れ子ができるので、それのことでしょうか?

コード:

#include <stdio.h>

void hogeFunc(int *a) {
	void fugaFunc(int *b) {
		(*b) *= 10;
	}

	fugaFunc(a);
	(*a) += 1;
}

int main(void) {
	int foo = 5;
	hogeFunc(&foo);
	printf("%d\n", foo);
	return 0;
}
(https://ideone.com/vY4yqD)

もちろん、普通に関数を入れ子にしない場合でも書き方は同じです。

コード:

#include <cstdio>

void fugaFunc(int *b) {
	(*b) *= 10;
}

void hogeFunc(int *a) {

	fugaFunc(a);
	(*a) += 1;
}

int main(void) {
	int foo = 5;
	hogeFunc(&foo);
	printf("%d\n", foo);
	return 0;
}
VANQUISH さんが書きました:ポインタを使用した関数内で再び内部関数に関数のポインタ引数を渡す事自体が間違いなのでしょうか。
「ポインタを使用した関数内で再び内部関数に関数のポインタ引数を渡す」の意味がよくわかりませんが、おそらく違います。
コンパイルエラーの原因は、ポインタを渡すべき場所にポインタを渡していないことだと思います。
例えば、345行目からの

コード:

/* キー入力 (各処理分岐関数) */
void InputInLines ( int hit[] , int pnt[][16] , int *opr , int *dir , int *sta , int *x , int *inc , int *chr , char *cnt ) 
{
	/* キー入力判断を行う */
	if ( Key[KEY_INPUT_RIGHT] > 0 ) {																	// 右キーが押されていたら、
		/* 処理 A */
		/* ステータス情報チェックを行う */
		if ( *sta == 1 ) {																				// 地上にいるなら、
			WalkSubroutine ( hit , pnt , 'R' , *opr , *dir , *x , *inc , *chr , *cnt ) ;								// 歩行処理を実行する (キー方向:R)
		} else if ( *sta == 2 ) {																		// 空中にいるなら、
			// 空力処理を実行する
		} else {																						// それ以外の場合は、
			// undefined
		}
この部分では、WalkSubroutineの第四引数に「oprに格納されているポインタが指す先に格納されているint型のデータ」を渡していますが、
52行目のプロトタイプ宣言

コード:

void WalkSubroutine ( int hit[] , int pnt[][16] , char a , int *opr , int *dir , int *x , int *inc , int *chr , char *cnt ) ;	// 歩行処理関数
によると、WalkSubroutineの第四引数にはint型のデータへのポインタを指定しないといけないので、
警告またはコンパイルエラーになる可能性があります。
第五~第九引数も同様に、ポインタを渡すべき場所にポインタでない型のデータが指定されています。
さらに、InputInLines関数の他のWalkSubroutineの呼び出しでも、同様の間違いがあります。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

box
記事: 2002
登録日時: 14年前

Re: C言語 - 内部関数へポインタ引数を渡すのは間違いなのか

#3

投稿記事 by box » 10年前

VANQUISH さんが書きました: コードの中でいうとWalkSubroutine関数のプロトタイプ宣言、WalkSubroutine関数定義部分の引数指定箇所が怪しいと思うのですが改変しても結果はコンパイルエラーでした。
およびInputInLines関数内でこのWalkSubroutineを呼び出しているのですが、ここの記述部分でコンパイラがコード警告(赤い波線)を出していてその内容が「"int"の引数は型"int *"のパラメータと互換性がありません」です。互換性とは一体何の事なのでしょうか。(・_・???

コード:

void InputInLines ( int hit[] , int pnt[][16] , int *opr , int *dir , int *sta , int *x , int *inc , int *chr , char *cnt ) 
{
			WalkSubroutine ( hit , pnt , 'R' , *opr , *dir , *x , *inc , *chr , *cnt ) ;							
こういう風に書いているということは、WalkSubroutine関数を呼び出すときの例えば第4引数は
int型を想定している(oprはint *なので、*oprはint型)のに、同関数の定義部では
VANQUISH さんが書きました:

コード:

/* 歩行処理 */
void WalkSubroutine ( int hit[] , int pnt[][16] , char a , int *opr , int *dir , int *x , int *inc , int *chr , char *cnt ) 
例えば第4引数はint *型になっています。
そういう食い違いがありますが、大丈夫ですか?
と、コンパイラーが教えてくれています。

WalkSubroutine関数の例えば第4引数は
int型なのか
int *型なのか
整理してみましょう。
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

アバター
VANQUISH
記事: 5
登録日時: 11年前
住所: 日本
連絡を取る:

Re: C言語 - 内部関数へポインタ引数を渡すのは間違いなのか

#4

投稿記事 by VANQUISH » 10年前

みけCATさん、boxさん、貴重なお知恵を誠に感謝します!
コンパイルエラーが出なくなりまして、改善点としてさきほどの、

コード:

//*****************************************
//
//
//		bank $07 [ function 3 - manual lv. ]
//
//
//*****************************************

/* キー入力 (各処理分岐関数) */
void InputInLines ( int hit[] , int pnt[][16] , int *opr , int *dir , int *sta , int *x , int *inc , int *chr , char *cnt ) 
{
	/* キー入力判断を行う */
	if ( Key[KEY_INPUT_RIGHT] > 0 ) {																	// 右キーが押されていたら、
		/* 処理 A */
		/* ステータス情報チェックを行う */
		if ( *sta == 1 ) {																				// 地上にいるなら、
			WalkSubroutine ( hit , pnt , 'R' , opr , dir , x , inc , chr , cnt ) ;								// 歩行処理を実行する (キー方向:R)
		} else if ( *sta == 2 ) {																		// 空中にいるなら、
			// 空力処理を実行する
		} else {																						// それ以外の場合は、
			// undefined
		}
	} else if ( Key[KEY_INPUT_LEFT] > 0 ) {																// 左キーが押されていたら、
		/* 処理 B */
		/* ステータス情報チェックを行う */
		if ( *sta == 1 ) {																				// 地上にいるなら、
			WalkSubroutine ( hit , pnt , 'L' , opr , dir , x , inc , chr , cnt ) ;								// 歩行処理を実行する (キー方向:L)
		} else if ( *sta == 2 ) {																		// 空中にいるなら、
			// 空力処理を実行する
		} else {																						// それ以外の場合は、
			// undefined
		}
関数を呼び出している部分(WalkSubroutine)の引数をコンマなしにしたところエラーが出ず正常にコンパイルされました。
要因としてはやはり引数の指定方法だったのだと思いますがこの場合、int型のポインタで宣言している場合はその中でint型のポインタを関数の引数に指定する状況でも*を付けないようにするというルールになっているという認識でよいのでしょうかね。
今思うともっと論理的に考えれば個人的に解決できたようにも思えるのですが、ポインタ引数を浸かっている関数の中では全て*(ポインタ名)を使うものという固定概念に捕らわれてしまっていたので師方々のコメントは非常に助かりました。ありがとうございます。

閉鎖

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