構造体内の配列
構造体内の配列
typedef struct {
char field[15][10];
} FIELDSTATE;
FIELDSTATE f_state;
f_state.field[15][10] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 5
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 10
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 15
};
これだと、構文エラーが出るんですが、だめなんですかね???
char field[15][10];
} FIELDSTATE;
FIELDSTATE f_state;
f_state.field[15][10] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 5
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 10
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 15
};
これだと、構文エラーが出るんですが、だめなんですかね???
Re: 構造体内の配列
追記
と宣言時に初期化リストを指定すればよいかと。
もっとも全部 0 でいいなら
FIELDSTATE f_state = {0};
のみでよさげ。
FIELDSTATE f_state = {
{
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 5
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 10
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 15
}
};
もっとも全部 0 でいいなら
FIELDSTATE f_state = {0};
のみでよさげ。
Re: 構造体内の配列
今テトリスを作っていまして、自分で作った*.hの中で
// フィールド
typedef struct {
char field[15][10];
} FIELDSTATE;
FIELDSTATE f_state = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 3
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 4
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 5
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 6
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 7
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 10
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 11
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 12
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 13
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 14
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 15
};
を*.hで宣言すると構文エラーになるんですけど、*.cppだとエラーにならないんですよ、ただ自分は*.hで構造体を宣言したいんです。
// フィールド
typedef struct {
char field[15][10];
} FIELDSTATE;
FIELDSTATE f_state = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 3
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 4
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 5
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 6
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 7
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 10
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 11
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 12
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 13
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 14
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 15
};
を*.hで宣言すると構文エラーになるんですけど、*.cppだとエラーにならないんですよ、ただ自分は*.hで構造体を宣言したいんです。
Re: 構造体内の配列
*.hをインクルードしている*.cppファイルはいくつありますか?
そしてどんなエラーがでているのでしょうか?
たぶん、extern指定子を使えばなんとかなるかと。
参考:http://www.geocities.jp/ky_webid/c/032.html
そしてどんなエラーがでているのでしょうか?
たぶん、extern指定子を使えばなんとかなるかと。
参考:http://www.geocities.jp/ky_webid/c/032.html
Re: 構造体内の配列
*.hをインクルードしてるファイルは5個あります。
typedef struct {
char field[15][10];
} FIELDSTATE;
FIELDSTATE f_state = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 3
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 4
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 5
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 6
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 7
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 10
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 11
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 12
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 13
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 14
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 15
};
このまま宣言すると、
構文エラー : '{'
'{' の前に予期しないトークンがありました。関数の本体は無視されます
'f_state' : 定義されていない識別子です。
'.field' の左側はクラス、構造体、共用体でなければなりません
typedef struct {
char field[15][10];
} FIELDSTATE;
FIELDSTATE f_state = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 3
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 4
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 5
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 6
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 7
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 10
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 11
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 12
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 13
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 14
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 15
};
このまま宣言すると、
構文エラー : '{'
'{' の前に予期しないトークンがありました。関数の本体は無視されます
'f_state' : 定義されていない識別子です。
'.field' の左側はクラス、構造体、共用体でなければなりません
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 14年前
- 住所: 東海地方
- 連絡を取る:
Re: 構造体内の配列
それで問題ないはずですので、ソースコード全体を提示したもらった方が良いかも知れません。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: 構造体内の配列
はて?tsutsu# さんが書きました: ストレージクラスが正しくありませんと言われました。
VC2010 でコンパイルしてみましたがC/C++どちらでも問題なくコンパイル/リンク出来ましたが...
/* a.h */
typedef struct {
char field[15][10];
} FIELDSTATE;
extern FIELDSTATE f_state;
/* a.c */
include "A.h"
FIELDSTATE f_state = { 0 };
int main()
{
return 0;
}
実際のコードとエラーメッセージを見せてください。
Re: 構造体内の配列
// *.h
//モードの基底クラスとモード変更時のフェード処理 #ifndef __MODESTRUCT__H
#ifndef __MODESTRUCT__H
#define __MODESTRUCT__H
#include "DxLib/DxLib.h"
class ModeStructer { // モードの基礎となる抽象クラス
protected:
char* name;
int number;
int ForDecide;
int ForCancel;
int Submit_Decide;// FALSE->NG TRUE->OK
int Submit_Cancel;// FALSE->NG TRUE->OK
public:
ModeStructer::ModeStructer(){
name = "enpty";
number = -1;
ForDecide = -1;
ForCancel = -1;
Submit_Decide = 0;
Submit_Cancel = 0;
}
virtual ModeStructer::~ModeStructer(){ // 抽象クラスの仮想デストラクタ
}
void SetData ( char* s, int n, int d, int c ){
name = s; // モードの名前
number = n; // モードの番号
ForDecide = d; // デフォルト
ForCancel = c; // デフォルト
}
void setDecide(int d) {
ForDecide = d;
}
void setCancel(int c) {
ForDecide = c;
}
virtual void init() = 0;//画像や音声、その他の初期化
virtual void enter() = 0;//モードに入る直前の処理
virtual void action() = 0;//モード内の動作
virtual void exit() = 0;//モードから抜ける直前の処理
void dispName() { printfDx ( "%s\n", name); };
void dispNumber() { printfDx ( "%d\n", number); };
};
class ModeChanger {
int alpha;
int phase;
int Completed;
int DecOrCan;
public:
ModeChanger::ModeChanger() {
alpha = 0;
phase = 0;
Completed = 0;
DecOrCan = 0;
};
int Fade ( int, int );
int FadeStream( int, int, int, int );
int GetPhase() { return phase; };
int GetComp() { return Completed; };
void SetPhase(int p) { phase = p; };
};
// モードの派生クラス設計図をここにまとめる
// mainでnewするときに充てる番号を指定して書いておくこと
// モード番号 : 0
class Title : public ModeStructer {
// 必須関数
public:
virtual void init(); virtual void enter();
virtual void action(); virtual void exit();
};
class Playing : public ModeStructer {
// 構造体の定義と宣言わここ
/* ゲームステータス */
typedef struct {
int Handle[5];
} GLOBALSTATE;
GLOBALSTATE g_state;
/* フィールドステータス */
typedef struct {
char field[15][10];
} FIELDSTATE;
extern FIELDSTATE f_state;
/*- ブロックステータス -*/
typedef struct {
int xPos, yPos;
int Speed;
int Handle[7];
int no;
} TETRISPLAYSTATE;
TETRISPLAYSTATE t_state;
public:
// 関数定義わここ
virtual void init(); virtual void enter();
virtual void action(); virtual void exit();
void TetrisMain ();
void BlockDisplay ( char(*field)[10], int Handle );
};
#endif
// *.c
#include "header/ModeStructer.h"
#include "header/extern.h"
#pragma warning (disable : 4244)
//ModeStructerクラスを継承し、各々のモード処理をactionとする
//そのモードで必要なメンバ変数の初期化、画像の読み込み
void Playing::init() {
// 基本的に画像の読み込みのみ
/*- 背景・ステータス -*/
g_state.Handle[0] = LoadGraph("data/bg.bmp");
/*- プレイヤ~ -*/
LoadDivGraph("data/parts.bmp", 7, 7, 1, 32, 32, t_state.Handle);
}
// モードに入るたびに行われる初期化
void Playing::enter() {
// 決定もしくはキャンセルして次のモードに行く事を許可するか禁止するか決めておきます
// 変数初期化わここ
Submit_Decide = FALSE;
Submit_Cancel = FALSE;
// ブロックステータス
t_state.xPos = 3;
t_state.yPos = 0;
t_state.Speed = 40;
t_state.no = 0;
}
void Playing::action() {
printfDx("プレイ中\n");
/*--------------------
* GAMEMAIN *
----------------------
*/
DrawGraph( 0, 0, g_state.Handle[0], TRUE );
// フィールドステータス
TetrisMain ( );
}
// モードを出た後の初期化
void Playing::exit() {
}
/*-------------------------------
* 関数名 : TetrisMain ( ) *
* 概要 : テトリスメイン *
---------------------------------
-*/
void Playing::TetrisMain ( )
{
char BlockShape[][6] = {
{-1, 0, 1, 0, 0, 1}, // Block 1
{ 0, -1, 0, 1, 1, 0}, // Block 2
{ 0, -1, -1, 0, 1, 0}, // Block 3
{ 0, -1, 0, 1, -1, 0}, // Block 4
};
t_state.Speed--;
if( t_state.Speed == 0 ){
t_state.Speed = 40;
f_state.field[t_state.yPos][t_state.xPos] = 0;
if( t_state.yPos < 14 ){
t_state.yPos++;
}
}
f_state.field[t_state.yPos][t_state.xPos] = 1;
for( int i = 0; i < 15; i++ ){
for( int j = 0; j < 10; j++ ){
if( f_state.field[i][j] != 0 ){
DrawGraph( (j * 32), i * 32, t_state.Handle[0], FALSE );
}
}
}
}
エラーコードは : 1>h:\project01\source\header\modestructer.h(86) : error C2071: 'Playing::f_state' : ストレージ クラスが正しくありません。
が出ます。
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 14年前
- 住所: 東海地方
- 連絡を取る:
Re: 構造体内の配列
エラーの原因は、C++のクラス定義の中でグローバル変数として定義しようとしているからです。
クラスのメンバ変数として定義したいなら、 は外に出して、 として下さい。
この場合は、初期値は宣言できないので、コンストラクタで初期化してください。
【修正】
あるいは、今の形のままクラス宣言の外に全て出してしまうかです。
これだとクラス定義されないグローバルな変数になります。
クラスのメンバ変数として定義したいなら、 は外に出して、 として下さい。
この場合は、初期値は宣言できないので、コンストラクタで初期化してください。
【修正】
あるいは、今の形のままクラス宣言の外に全て出してしまうかです。
これだとクラス定義されないグローバルな変数になります。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: 構造体内の配列
f_stateはメンバですのでクラスごと違う値を持ちたいということであれば、
externはとって、コンストラクタで初期化してください。
だたし、前述の通り、宣言時にしか初期化リストは使えないので、memsetとかを使って0で初期化してください。
グローバル変数のように、クラスごと違う値でなくてもよいのであれば、
staticメンバ変数にして、*.cppで実態を定義してください。
externはとって、コンストラクタで初期化してください。
だたし、前述の通り、宣言時にしか初期化リストは使えないので、memsetとかを使って0で初期化してください。
グローバル変数のように、クラスごと違う値でなくてもよいのであれば、
staticメンバ変数にして、*.cppで実態を定義してください。