2011-07-25 20 views
0

私はSDLを使って簡単なプログラムを書いていますが、私は奇妙な問題にぶち当たっています。まずコード:問題グローバル変数ヘッダーファイルの配列を初期化するC++

#ifndef GLOBAL_VARIABLES_H 
#define GLOBAL_VARIABLES_H 

#include <string> 
#include <cassert> 
#include "SDL.h" 
#include "SDL_image.h" 
using std::string; 

const int SCREEN_WIDTH = 800; 
const int SCREEN_HEIGHT = 600; 
const int SCREEN_BPP = 32; 

const string MAIN_BACKGROUND_FILENAME = "tempBackground.jpg"; 



SDL_Rect CARD_CLIPS[2]; 

const int CARD_BACK = 0; 
const int CARD_FRONT = 1; 

CARD_CLIPS[CARD_BACK].h = 196; 
CARD_CLIPS[CARD_BACK].w = 286/2; 
CARD_CLIPS[CARD_BACK].x = 286/2; 
CARD_CLIPS[CARD_BACK].y = 0; 

CARD_CLIPS[CARD_FRONT].h = 196; 
CARD_CLIPS[CARD_FRONT].w = 286/2; 
CARD_CLIPS[CARD_FRONT].x = 0; 
CARD_CLIPS[CARD_FRONT].y = 0; 

#endif 

私は取得していますエラーはこれです:私はSDL_Rectの要素を初期化しようとするたびに

1>c:\users\--\global variables.h(23): error C2466: cannot allocate an array of constant size 0 

1>c:\users\--\global variables.h(23): error C2143: syntax error : missing ';' before '.' 

1>c:\users\--\global variables.h(23): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int 

1>c:\users\--\global variables.h(23): error C2371: 'CARD_CLIPS' : redefinition; different basic types 

1>c:\users\--\global variables.h(18) : see declaration of 'CARD_CLIPS' 

繰り返し同じエラー。

SDLの部分は問題とは関係ありません。 int配列を宣言して同じ方法で初期化しようとすると、まったく同じエラーが発生します。私がmain.cppにこれを置くと、それは完全にうまく動作します。

ありがとうございました。追加情報が必要な場合はお知らせください。

EDIT:ヘッダーファイルで配列を使用しようとするとき以外はエラーが発生しないことに注意してください。従来のやり方を理解するために何をしているのですが、基本的な観点から、このようなヘッダファイルで配列を宣言して初期化することができない理由を理解したいと思います。

+0

クラスSDL_Rectはどのように定義されていますか? SDL_Rectでは、デフォルトコンストラクタを使用してオブジェクトを作成することはできません。 – mukeshkumar

+0

SDL_Rectとは関係がありません。私が言ったように、intやその他のものを使用しようとすると同じエラーが発生します。 – Slims

答えて

4

最初に、変数定義はヘッダーファイルには入れないでください。extern宣言だけです。

第2に、定義内の変数(配列を含む)を初期化したり、関数を関数内の実行可能ステートメントとして割り当てることができます。実行可能な文をファイルスコープに入れることはできません。


配列の初期化は、次のようになります。

int a[4] = { 1, 4, 9, 16 }; 

このようにしない:

int a[4]; 
a[0] = 1; // ILLEGAL outside a function! 
a[1] = 4; 
a[2] = 9; 
a[3] = 16; 
+0

私はなぜこれをしなければならないのか分かりません。 Main.cppのメイン変数の上にグローバル変数を置くだけではなく、ヘッダファイルの変数をどのように初期化するのでしょうか?申し訳ありません、私は新しいプログラマーです。これらの変数は、複数の異なるファイルにまたがってグローバルにする必要があります。他のすべてのファイルが#includeできるヘッダーファイルに入れておくよりも、これを行うより良い方法は何ですか? – Slims

+0

@Slims "extern"キーワードはあなたの友人です。非常に、非常にスリムな例:global.cpp宣言int g_myGlobal = 111; main.cppではextern int g_myGlobalを使います。 – celavek

+0

私はそれをして、私はまったく同じエラーメッセージを得ました。グローバル変数ヘッダーファイルには、配列以外の宣言や変数の初期化があり、externを使わずに正常に動作することに注意してください。エラーが発生する場所で配列を使用する場合のみです。 – Slims

1

This articleをヘッダファイルに含まれるべきかについていくつかのガイドラインを提供するかもしれません。 タイトルにはCがありますが、もちろんC++にも当てはまります。

1

Ben Voigtはすでに説明したように、あなたの問題はヘッダーファイルとは関係ありません。宣言ではない通常の実行可能文を、名前空間のスコープ(つまり、関数やクラスの外側)に直接置くだけです。できません。

この文は、技術的に細かいです:

const int CARD_BACK = 0; 

それが宣言されるので、それは技術的には大丈夫です。割り当てはありません。 =ここでは代入を示すのではなく、宣言構文の一部であり、イニシャライザが続くことを示します。

私は本当にマクロのために大文字の名前を予約する必要がありますが、コンパイラは気にしないので「技術的に」と言います。一方

は、この文は、名前空間スコープでOKではありません。

CARD_CLIPS[CARD_BACK].h = 196; 

それは宣言ではありませんのでです。つまり、それは新しい名前を導入していない:それは割り当てます。

ああ、私の目はすべて大文字です!

乾杯、

+0

すみません、私はまあまあです。私の前学期の学期は、グローバル変数を宣言するときにすべての大文字を使うべきだと教えてくれました。これは間違っていますか? – Slims