• ベストアンサー

文字列の配列について

教えてください。 1.文字列の配列はどのように宣言すればよいのでしょうか? char [3][3][20] = {{"朝","昼","晩"},{"morning","evening","night"},{"6:00","12:00","18:00"}}; これでできるとおもうのですが、もっと効率的な宣言ってあるのでしょうか? 2.また、この変数を3つのソースファイルで使用できるグローバル変数にしたいのですが、どのように宣言すればよいのでしょうか? リンカエラー(外部シンボルが未解決)が発生してしまい、困っています。 def.h(ここで宣言したい)  -----|----  |   |   | A.h  B.h C.h  |   |   | A.cpp B.cpp C.cpp ちなみにBorland C++ Builder5を使っています。

質問者が選んだベストアンサー

  • ベストアンサー
  • a-kuma
  • ベストアンサー率50% (1122/2211)
回答No.3

> どのようにクラス化をすればよいか教えていただければ幸いです あくまでも一例として読んで下さい。 「定義情報」のように、プログラムの中でインスタンスがひとつで良いものを実装する やり方に Singleton パターンというのがあります。 例えば、こんな感じ。どんな定義情報か分からないんで、時刻情報を扱うクラスだと 思って名前をつけます。 ◆ ヘッダ class TimeRangeInfo { private: TimeRangeInfo(); static TimeRangeInfo* timerangeinfo_g; public: static TimeRangeInfo* Instance(); // 定義アクセス用のメソッド const char* getLabel(int hour, int minute) const; }; ◆ソース #include "timerangeinfo.h" TimeRangeInfo* TimeRangeInfo::timerangeinfo_g = NULL; TimeRangeInfo* TimeRangeInfo::Instance() { if (timerangeinfo_g == NULL) { timerangeinfo_g = new TimeRangeInfo; } return timerangeinfo_g; } TimeRangeInfo::TimeRangeInfo() { // 定義の内容を自分のメンバーに登録する } const char* TimeRangeInfo::getLabel(int hour, int minute) const { // 自分で持っている定義情報から hour、minute にあたる情報を抜き出す return 抜き出した値; } ◆使う人 #include "timerangeinfo.h" // 16:50 は、どんな区分か? cout << TimeRangeInfo::Instance()->getLabel(16, 50) << endl; という感じです。 # コンパイルなんかはしてないけど、勘弁 m(_ _)m 定義情報にアクセスするためのキーが何か存在するでしょうから、それを引数に した情報取得用のメソッドを必要な分だけ作れば良い。 このクラス内部に、どのように定義情報を持つかは、外部には隠蔽されている のだから、どんな風にやっても良いですね。例えば、外部変数とするにしても static な(つまり、extern ではない)スコープにすれば、あまり影響は出ない ですし。 ◆ TimeRangeInfo クラスのソース #include "timerangeinfo.h" TimeRangeInfo* TimeRangeInfo::timerangeinfo_g = NULL; static const char* data[100][256] = { {"data-1", "data-2", .... //延々とデータが続く 100×256 のデータのキーが何か想像がつかない(100種類のキーに対して、 データが 256 個もあるの?)のですが、私だったら、hash_map なんかを 使うかなあ。 # でも、TimeRangeInfo クラスの内部に隠蔽されているから、何を使っても # 後で変更するのは簡単ですよね。

soraprio
質問者

お礼

パソコンが調子悪く回答に送れて申し訳ありませんでした。 なるほど、いろいろ勉強になりました。 しかし、C++とはなんておくが深いものなのでしょう。 重ね重ね、ご丁寧にありがとうございました。

その他の回答 (2)

  • a-kuma
  • ベストアンサー率50% (1122/2211)
回答No.2

> 2.また、この変数を3つのソースファイルで使用できるグローバル変数にしたい グローバル変数にすること自体はお勧めできませんが、やり方だけ。 No.1 の回答でも問題はないんですが、A.cpp ~ C.cpp は、この時刻の定義を 使う、という意味で同じ位置付けですから、A.cpp だけ特別、ってのはあまり 良くないですね。 というわけで、グローバル変数の定義をするソースだけを作ってしまいましょう。 (例えば、)def.h は、 extern const char g_timerange[3][3][20]; def.cpp を作って、 #include "def.h" const char g_timerange[3][3][20] = {{"朝","昼","晩"},{"morning","evening","night"},{"6:00","12:00","18:00"}}; A.cpp などでは、def.h をインクルードして使います。リンクの際には def.o も リンクの対象にします。 質問の範囲を多少超えますが、どうしてもグローバル変数にするのであれば、 ・値の定義として使うのだから、書き込みができないように const 宣言をつけよう ・名前の衝突を考えて、なるべくユニークになるように冗長度の高い変数名にしよう というアドバイスを付け加えておきます。 後、蛇足をもうひとつ。 せっかく、C++ なんですから、文字列の配列にするよりも、「時間の定義を知っている クラス」として実装する方が良い、と思いますよ。

soraprio
質問者

お礼

a-kumaさん、いつも丁寧な回答ありがとうございます。 やっぱりグローバル変数は良くないのですね。それをクラス化ですか? 例では非常に少ない文字と量ですが作ろうとしているのは、[100][256][80]位の大きい文字配列です。 A.cpp,B.cpp,C.cppからそれぞれその文字データを取り出そうと考えているのですが、どのようにクラス化をすればよいか教えていただければ幸いです。 宜しくお願いします。

  • yatokesa
  • ベストアンサー率40% (201/496)
回答No.1

1. お書きになられたコードがもっとも効率的です。 2. def.hで実体を宣言するのなら、A.cppだけで def.hをインクルードし、他のB.cpp, C.cppでは extern宣言をします。 extern char hoge[3][3][20];

soraprio
質問者

お礼

早速の回答ありがとうございました。

関連するQ&A