コンパイル時のエラーについて

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
T.C.D

コンパイル時のエラーについて

#1

投稿記事 by T.C.D » 16年前

初質問です。基本的な内容なら分かる程度のレベルです。
XPでVC++2008を使っているのですが、どうしても分からないエラー(コンパイル時)が起きました。

ーーーーーmein.cを全て公開しました。ーーーーー

ソース"main.c"
/*数を当てるゲーム*/
/*文字を入れた場合の問題あり*/

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "game.h"
#include "timer.h"

	//変数
    int num[s_size],
		rep, cnt = 0,
		yosou, answer = -1,worng,
		i, hugou, sa;
    int* p;


int main()  {

	FILE *fp;			//ファイルポインタ*
	puts("ゲーム...\nランキング...");

    for (i = 0; i <= s_size; i++) //念のためnum全てに0を代入
        num = 0;
    puts(" [数あてゲーム]");
    printf("スタートランクを指定してください(スタートは1~5(最大%d)) >",rank_max);
    scanf_s("%1d",&g_va.rank);
	if(!(g_va.rank>0 && g_va.rank<=5)) { //もしエラーなら
		error();
        g_va.rank = 1;
		main();
    }
	g_va.tp = g_va.rank * 3;
	puts("・・・・・・・・・・・・・・・・・・・・・・・・・");

	do {
        yosou = -1;
        cnt   = 0,worng = 0;
        p='\0';

        printf("STAGE%d[現在 ランク%d]\nゲームのレベルを選択してください。(1~100) ",g_va.tp,g_va.rank);
        scanf_s("%d",&g_va.level);
        if(!(g_va.level>0 && g_va.level<=100)) {
            printf("\n\tErorr\n\n");
            continue;
		}
		sistem(&g_va);

		printf("\t---1から%dまでの乱数を予想せよ!(回数制限=%d)---\n",g_va.kazu,g_va.over);
        //注:現段階では、文字を入力しないでください!

        while(yosou != answer) {		//メイン
            if(cnt>=g_va.over){			//もし回数制限を越えていたら終了
                puts("GAMEOVER!!");
            }
			kaitou();
        }
		sleep(1000);

        printf("おめでとうございます。「%d回」で正解しました!\n\n",cnt);
        printf("----------入力履歴----------\n"); //入力履歴表示&プラスマイナスいくつか
        printf(" 1回目 : %3d\n",num[0]);
        for(i = 1; i < cnt; i++) { //前後の数値の差の絶対値  及び  '+'or'ー'を求めるため
            if(cnt>=s_size)
                continue;
            p = &num;
            if (*p < *(p-1)) {  //前の数より*Pの方が小さい

                hugou = '-'; //-
                sa    = *(p-1) - *p;

            } else if(*p > *(p-1)){ //前の数より*Pの方が大きい

                hugou = '+'; //+
                sa    = *p - *(p-1);

            } else {            //前の数と*Pが等しい

                printf("%2d回目 : %3d (±0)\n",i+1,*p);
                continue;
            }
            printf("%2d回目 : %3d (%c %d)\n",i+1,*p,hugou,sa);
        }
        if (cnt<=5 && cnt>1)
            printf("5回以内で正解!お見事!\n");
        if(cnt==1)
            printf("….\n\n");
        g_va.score += g_va.level * g_va.rank;         //スコア表示と計算
		g_va.rank = g_va.tp++ / 3;			//ランク変更(後置インクリメント)
        if(g_va.rank>rank_max)
            g_va.rank = rank_max;
		sleep(3000);
        printf("現在のスコアは%dです\nもう一度やりますか?Yes..1 No..0 >",g_va.score);
        scanf_s("%d",&rep);

		for(i = 1; i <= 10; i++)
			printf("\n");
        puts ("----------------------------\n\n");

	} while (rep == 1);
}

//問題に解答する
void kaitou(void) {

			putchar ('>');
            scanf_s("%d",&yosou);
            if (cnt<s_size)
                num[cnt] = yosou; //num[0~cut]に入力値を代入(s_size回まで)

            if (!(1<=yosou && yosou<=g_va.kazu)) {
                printf("\t\a\aError 1から%dまでの数ではありません\n",g_va.kazu);
                cnt--;      //num[/url]への場所を戻す
                worng++;
                if (worng>=5)
                    printf("エラーを確認しましたか?\n");
            }else if (answer == yosou+1 || answer == yosou-1) {
                printf("惜しい!(%d回目)\n",cnt+1);
            }else if (yosou < answer){
                printf("\aもっと大きい数です(%d回目)\n",cnt+1);
            }else if (yosou > answer){
                printf("\aもっと小さい数です(%d回目)\n",cnt+1);
            }
            cnt++;
}


//数を決定する
void sistem(struct variable *g_va) {

		//回数制限...150-レベル+?÷ランク
		g_va->over = (150 - g_va->level + (num[0] % 10 /2)) / g_va->rank ;
        if (g_va->over<2)
            g_va->over = 2;
        else if (g_va->over>100)
            g_va->over = 100;

		//数の上限...レベル×10+? の100~190%
        g_va->kazu = (g_va->level * 10 + (num[0] % 10)) * (1.0 + (g_va->rank - 1.0) / 10.0);

        //(乱数の発生)
        srand((unsigned)time(NULL));
        answer = (rand() % g_va->kazu) + 1;
}

また、これがtimer.hは、xミリ秒待つ関数です。
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
リンクしています...
ERROR.obj : error LNK2005: _g_va は既に main.obj で定義されています。
D:\data\My Data\Visual Studio 2008\Projects\game\Debug\game.exe : fatal error LNK1169:
1 つ以上の複数回定義されているシンボルが見つかりました。
game - エラー 2、警告 2
========== ビルド: 0 正常終了、1 失敗、0 更新不要、0 スキップ ==========
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

 上のように、「1 つ以上の複数回定義されているシンボルが見つかりました。」と出力ウィンドウにありますが、この意味が分かりません。ちなみに、"g_va"はヘッダファイルで構造体としてのみ宣言しています。

box

Re:コンパイル時のエラーについて

#2

投稿記事 by box » 16年前

自作のヘッダーファイルがあるのでしたら、
それを含めて、そのプログラムに関する
すべてのソースコードを見せていただきたいです。

T.C.D

Re:コンパイル時のエラーについて

#3

投稿記事 by T.C.D » 16年前

すみません、忘れていました。
これがそのヘッダーファイルです。

game.h
#ifndef _MYGAME_
#define _MYGAME_

#define s_size 50
#define rank_max 10

	//ゲームシステム関係の変数(構造体)
	//ソースはva.[変数]の形で使用
	struct variable{
		short score,
			  level,
			  rank,
			  tp,
			  over,
			  kazu;
	};
	struct variable g_va = {0, 0, 1, 1};
	
void error(void);
void kaitou(void);
void sistem(struct variable *g_va);


#endif

box

Re:コンパイル時のエラーについて

#4

投稿記事 by box » 16年前

全部見せてくださいましたか?

>ERROR.obj : error LNK2005: _g_va は既に main.obj で定義されています。

このメッセージからは、main.c と ERROR.c という
ソースファイルがあるように見えます。

ERROR.c の内容は、今のところ見えておりません。

また、先に見せてくださっていた main.c には
ヘッダーファイルをインクルードしている箇所が見あたりませんでした。

そういった点を含めて、「すべてを」見せてほしいとお願いしております。
どうせなら一度にさらけ出した方が、早く解決すると思います。

sizuma

Re:コンパイル時のエラーについて

#5

投稿記事 by sizuma » 16年前

mainで変数の定義となにをincludeしてるのかわかりません。
複数回定義されてる、んだったらそこらへんが怪しいと思うんですけど・・・



#ボーっとしてたらかぶりました・・・

T.C.D

コンパイル時のエラーについて -追記2

#6

投稿記事 by T.C.D » 16年前

二回目ですみません。これで全てだと思います。(main.c のmain以外の関数を除いて)
このソースはご覧のとおりとても短いので、はじめは載せませんでした。
#include <stdio.h>
#include "game.h"

void error(void) {
	printf("\t---Erorr---\n");
}
それから、分かりやすいようにコンパイル済みの途中段階の実行ファイルを添付しました(LZH)。
(デバック用ですので、少しソースとは違うかもしれません)

box

Re:コンパイル時のエラーについて -追記2

#7

投稿記事 by box » 16年前

> #include <stdio.h>
> #include "game.h"

main.c でも同じようにインクルードしているのですか?

つまり、複数の .c ファイルから同じ game.h を
インクルードしているかどうか、そこがいちばん知りたい点なのです。

まあ、おそらく、そういう風にインクルードしているのでしょうけれど。
リンク時(コンパイル時ではないです)のエラーメッセージから推測して。

>	struct variable g_va = {0, 0, 1, 1};

結果として、この変数定義を
main.c
ERROR.c
の両方で行なっている点が問題であると思います。

T.C.D

Re:コンパイル時のエラーについて

#8

投稿記事 by T.C.D » 16年前

確かに、両方でインクルードしているようでした。boxさん、ありがとうございます。
ところで、私はgame.h に
#ifndef _MYGAME_
#define _MYGAME_

・・・

#endif
と言う風に書き、二重インクルードを防いだはずなのですが、
なぜ二回インクルードしてしまったのでしょか?
どなたか教えてください。

*一番最初のを編集し直してmain.cを全て公開することにしました。

zwi

Re:コンパイル時のエラーについて

#9

投稿記事 by zwi » 16年前

>#ifndef _MYGAME_
これは1つのソースで二重のヘッダの読み込みを防ぐためのものです。
今回の問題は同じグローバル変数が別々のソースで定義されたことになるので、まったく別の問題です。
そもそも、グローバル変数の実体定義をヘッダに書いたのが間違いです。

T.C.D

Re:コンパイル時のエラーについて

#10

投稿記事 by T.C.D » 16年前

ありがとうございました。ある程度解決しました。

閉鎖

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