ページ 11

再定義について

Posted: 2012年9月04日(火) 19:07
by イマダニ
こんにちは。いつもお世話になっております。
まず矩形を作るためのRECT構造体を作り、

コード:

#ifndef DEF_RECT_H
#define DEF_RECT_H

typedef struct{   
	int left;
	int top;
	int right;
	int bottom;
}RECT;

int makeRect(int x,int y,int w,int h);
bool checkRect(RECT rect1,RECT rect2);

#endif
そして矩形を作る関数と二つの矩形の当たり判定を確認する関数を作りました。

コード:

#include "DxLib.h"
#include "RECT.h"

int makeRect(int x,int y,int w,int h){
	RECT *to;
	to->left=x;
	to->top=y;
	to->right=x+w;
	to->bottom=y+h;
	return (to);
}

bool checkRect(RECT rect1,RECT rect2){
	if(rect1.right  < rect2.left)return false;
	if(rect2.right  < rect1.left)return false;
	if(rect1.bottom < rect2.top )return false;
	if(rect2.bottom < rect1.top )return false;

	return true;
}
これをコンパイルするとこんなエラーが


1>------ ビルド開始: プロジェクト: action, 構成: Debug Win32 ------
1>コンパイルしています...
1>RECT.cpp
1>c:\users\shun\desktop\action\rect.h(9) : error C2371: 'RECT' : 再定義されています。異なる基本型です。
1> c:\program files\microsoft sdks\windows\v6.0a\include\windef.h(324) : 'RECT' の宣言を確認してください。
1>c:\users\shun\desktop\action\rect.cpp(10) : error C2440: 'return' : 'RECT *' から 'int' に変換できません。
1> この変換が可能なコンテキストはありません。
1>ビルドログは "file://c:\Users\shun\Desktop\action\Debug\BuildLog.htm" に保存されました。
1>action - エラー 2、警告 0
========== ビルド: 0 正常終了、1 失敗、0 更新不要、0 スキップ ==========

ifndefで囲んでいるのになぜ再定義とみなされるのか。
アドバイスお願いします。

Re: 再定義について

Posted: 2012年9月04日(火) 19:16
by softya(ソフト屋)
windows.h(正確にはwindef.h)内にRECT構造体があるからです。
こういう基本的に有りそう名前は使わないほうが良いですが構造を見る限りwindows.hの物を利用してはどうでしょうか?
http://msdn.microsoft.com/en-us/library ... 85%29.aspx

わざわざ自分で定義する必要はないと思います。

Re: 再定義について

Posted: 2012年9月04日(火) 19:24
by box
それはそうと、
イマダニ さんが書きました:

コード:

int makeRect(int x,int y,int w,int h){
	RECT *to;
	to->left=x;
	to->top=y;
	to->right=x+w;
	to->bottom=y+h;
	return (to);
}
ポインター to がどこを指しているかわからないのに、to->left とか書いて大丈夫でしょうか。
また、関数の戻り値の型と、実際に return している型とが食い違っているのは大丈夫でしょうか。

Re: 再定義について

Posted: 2012年9月04日(火) 21:56
by イマダニ
ひとまずソフト屋さんの教えにより再定義の理由がわかったので、
コードを書き換えてみました。

コード:

#include "DxLib.h"
#include "windows.h"

int makeRect(int x,int y,int w,int h){
	RECT to;
	to.left=x;
	to.top=y;
	to.right=x+w;
	to.bottom=y+h;
	return (to);
}

bool checkRect(RECT rect1,RECT rect2){
	if(rect1.right  < rect2.left)return false;
	if(rect2.right  < rect1.left)return false;
	if(rect1.bottom < rect2.top )return false;
	if(rect2.bottom < rect1.top )return false;

	return true;
}
これにより再定義のエラーは消えました。
ありがとうございます。
ですが、まだ

1>error C2440: 'return' : 'RECT ' から 'int' に変換できません。
1> この変換が可能なコンテキストはありません。

というエラーが出ます。
戻り値に構造体を使うのは初めてなのでどういう原因なのか正直よくわかりません。
そのために、boxさんに指摘された間違い起してしまったりしてます。
このエラーは何が原因なのでしょうか?

Re: 再定義について

Posted: 2012年9月04日(火) 22:01
by softya(ソフト屋)
関数名の前に書くのは戻り値の型でなくてはいけません。
int makeRect(int x,int y,int w,int h){
だとint型を返す関数となってしまいます。
RECT型を返す関数とすれば問題ありません。

あとwindows.hはDxLib.h内部でincludeされているので不要です。

Re: 再定義について

Posted: 2012年9月04日(火) 22:04
by box
イマダニ さんが書きました:

コード:

int makeRect(int x,int y,int w,int h){
	RECT to;
	return (to);
return 文で、RECT 型の値を戻していますね。
それに対して、makeRect の先頭では、戻り値が int 型であると書いています。
食い違っていませんか?ということです。
本当に int 型でいいんですか?

Re: 再定義について

Posted: 2012年9月04日(火) 22:11
by イマダニ
そうか!構造体が型を作るっていう基本的なことを忘れてました!

コード:

#include "DxLib.h"

RECT makeRect(int x,int y,int w,int h){
	RECT to;
	to.left=x;
	to.top=y;
	to.right=x+w;
	to.bottom=y+h;
	return (to);
}

bool checkRect(RECT rect1,RECT rect2){
	if(rect1.right  < rect2.left)return false;
	if(rect2.right  < rect1.left)return false;
	if(rect1.bottom < rect2.top )return false;
	if(rect2.bottom < rect1.top )return false;

	return true;
}
エラーを出さず、コンパイルできました。これで当たり判定ができます!
またいくつか勉強になりました。
soft屋さん、boxさんアドバイスありがとうございました!