新手请教一下c语言变量定义的问题

我的工程里有3个.cpp和2个.h,在cpp文件里定义了几个全局变量,然后两个cpp里都引用了一个.h,结果build的时候就出现
already defined in ***.obj,
conflicts with use of other libs,
one or more multiply defined symbols found

报错信息如下
Main.obj : error LNK2005: "int (* iMap)[13]" (?iMap@@3PAY0N@HA) already defined in LessonX.obj
Main.obj : error LNK2005: "bool g_bStart" (?g_bStart@@3_NA) already defined in LessonX.obj
Main.obj : error LNK2005: "float g_fGameTime" (?g_fGameTime@@3MA) already defined in LessonX.obj
Main.obj : error LNK2005: "int g_iScore" (?g_iScore@@3HA) already defined in LessonX.obj
LINK : warning LNK4098: defaultlib "LIBC" conflicts with use of other libs; use /NODEFAULTLIB:library
......\Bin\Game.exe : fatal error LNK1169: one or more multiply defined symbols found
执行 link.exe 时出错.

LessonX.cpp的源代码如下:
/////////////////////////////////////////////////////////////////////////////////
//
//
//
//
/////////////////////////////////////////////////////////////////////////////////
#include
#include "CommonAPI.h"
#include "LessonX.h"
#include "List.h"
////////////////////////////////////////////////////////////////////////////////
//
int g_iGameState = 0; // 游戏状态,0 -- 游戏结束等待开始状态;1 -- 按下空格键开始,初始化游戏;2 -- 游戏进行中
struct Weapon* g_pMyTank =NULL;
int iMap[11][13];
bool g_bStart = false; // 控制一局游戏开始true与结束false
float g_fGameTime = 0.f; // 一局游戏的剩余时间
int g_iScore = 0; // 一局游戏得分

const float GAME_TIME = 30.f; // 一局游戏时间
const float CREATE_TANK_TIME = 5.f; // 每批次生成坦克的时间间隔
const float TANK_SPEED = 5.f; // 坦克速度
const float BULLET_SPEED = 8.f; // 子弹速度
const float FIRE_TIME = 2.f; // 坦克开炮时间间隔
const float WORLD_LEFT = -26.f; // 游戏场景边界左值
const float WORLD_TOP = -22.f; // 游戏场景边界左值
const float WORLD_RIGHT = 26.f; // 游戏场景边界左值
const float WORLD_BOTTOM = 22.f; // 游戏场景边界左值//

// 游戏地图,0表示此处为空,1表示此处有墙。根据游戏空间大小、墙以及坦克大小,
// 我们把地图分成11行,13列,每格大小刚好放一块墙。

//
void GameInit();
void GameRun( float fDeltaTime );
void GameEnd();
void MoveMyTank(int iKey,bool bPress);

//==============================================================================
//
// 大体的程序流程为:GameMainLoop函数为主循环函数,在引擎每帧刷新屏幕图像之后,都会被调用一次。

//==============================================================================
//
// 游戏主循环,此函数将被不停的调用,引擎每刷新一次屏幕,此函数即被调用一次
// 用以处理游戏的开始、进行中、结束等各种状态.
// 函数参数fDeltaTime : 上次调用本函数到此次调用本函数的时间间隔,单位:秒
void GameMainLoop( float fDeltaTime )
{
switch( g_iGameState )
{
// 初始化游戏,清空上一局相关数据
case 1:
{
GameInit();
g_iGameState = 2; // 初始化之后,将游戏状态设置为进行中
}
break;

    // 游戏进行中,处理各种游戏逻辑
case 2:
    {
        // TODO 修改此处游戏循环条件,完成正确游戏逻辑
        if( true )
        {
            GameRun( fDeltaTime );
        }
        else
        {
            // 游戏结束。调用游戏结算函数,并把游戏状态修改为结束状态
            g_iGameState    =   0;
            GameEnd();
        }
    }
    break;

    // 游戏结束/等待按空格键开始
case 0:
default:
    break;
};

}
void MoveMyTank(int iKey,bool bPress)
{
if(bPress&&g_pMyTank!=NULL)
{
switch(iKey)
{
case KEY_W:
g_pMyTank->iDir=UP;
g_pMyTank->fSpeedX=0.f;
g_pMyTank->fSpeedY=-TANK_SPEED;
break;
case KEY_S:
g_pMyTank->iDir=DOWN;
g_pMyTank->fSpeedX=0.f;
g_pMyTank->fSpeedY=TANK_SPEED;
break;
case KEY_A:
g_pMyTank->iDir=LEFT;
g_pMyTank->fSpeedX=-TANK_SPEED;
g_pMyTank->fSpeedY=0.f;
break;
case KEY_D:
g_pMyTank->iDir=RIGHT;
g_pMyTank->fSpeedX=TANK_SPEED;
g_pMyTank->fSpeedY=0.f;
break;
default:
break;

}
dSetSpriteLinearVelocity("player",g_pMyTank->fSpeedX, g_pMyTank->fSpeedY);
dSetSpriteRotation("player",g_pMyTank->iDir*90);
}
}

//==============================================================================
//
// 每局开始前进行初始化,清空上一局相关数据
void GameInit()
{
}
//==============================================================================
//
// 每局游戏进行中
void GameRun( float fDeltaTime )
{
}
//==============================================================================
//
// 本局游戏结束
void GameEnd()
{
}
//==========================================================================
//
// 鼠标移动
// 参数 fMouseX, fMouseY:为鼠标当前坐标
void OnMouseMove( const float fMouseX, const float fMouseY )
{

}
//==========================================================================
//
// 鼠标点击
// 参数 iMouseType:鼠标按键值,见 enum MouseTypes 定义
// 参数 fMouseX, fMouseY:为鼠标当前坐标
void OnMouseClick( const int iMouseType, const float fMouseX, const float fMouseY )
{

}
//==========================================================================
//
// 鼠标弹起
// 参数 iMouseType:鼠标按键值,见 enum MouseTypes 定义
// 参数 fMouseX, fMouseY:为鼠标当前坐标
void OnMouseUp( const int iMouseType, const float fMouseX, const float fMouseY )
{

}
//==========================================================================
//
// 键盘按下
// 参数 iKey:被按下的键,值见 enum KeyCodes 宏定义
// 参数 iAltPress, iShiftPress,iCtrlPress:键盘上的功能键Alt,Ctrl,Shift当前是否也处于按下状态(0未按下,1按下)
void OnKeyDown( const int iKey, const bool bAltPress, const bool bShiftPress, const bool bCtrlPress )
{ if(iKey == KEY_SPACE && g_bStart == false) // 游戏未开始,按下空格键
{
g_bStart = true;
g_fGameTime = GAME_TIME;
dSetSpriteVisible("start", false);
dSetTextValue("time", (int)g_fGameTime);
dSetTextValue("score", g_iScore);
}
}
//==========================================================================
//
// 键盘弹起
// 参数 iKey:弹起的键,值见 enum KeyCodes 宏定义
void OnKeyUp( const int iKey )
{

}
//===========================================================================
//
// 精灵与精灵碰撞
// 参数 szSrcName:发起碰撞的精灵名字
// 参数 szTarName:被碰撞的精灵名字
void OnSpriteColSprite( const char *szSrcName, const char *szTarName )
{

}
//===========================================================================
//
// 精灵与世界边界碰撞
// 参数 szName:碰撞到边界的精灵名字
// 参数 iColSide:碰撞到的边界 0 左边,1 右边,2 上边,3 下边
void OnSpriteColWorldLimit( const char *szName, const int iColSide )
{

}

List.h的源代码如下:
//////////////////////////////////////////////////////////////
///////////////////////////
//////
//
////////////////////////////
#ifndef LIST_H
#define LIST_H
/////////////////////////////
struct Weapon{
char szName[128]; // 精灵名称
float fPosX, fPosY; // 精灵坐标
float fSpeedX, fSpeedY; // X和Y方向上速度
float fFireTime; // 敌方坦克距下一次开炮的剩余时间
int iHp; // 生命值
int iDir; // 朝向:0 - 上方;1 - 右方;2 - 下方;3 - 左方
int iType; // 类型: 0 - 我方坦克;1 - 敌方坦克;2 - 我方
// 子弹; 3 - 敌方子弹
Weapon* pNext; // 指向下一个节点的指针
};

enum Direction{
UP = 0, // 上方
RIGHT = 1, // 右方
DOWN = 2, // 下方
LEFT = 3 // 左方
};

enum Role
{
MYTANK = 0, // 我方坦克
ENEMYTANK = 1, // 敌方坦克
MYBULLET = 2, // 我方子弹
ENEMYBULLET = 3 // 敌方子弹
};
extern int g_iGameState; // 游戏状态,0 -- 游戏结束等待开始状态;1 -- 按下空格键开始,初始化游戏;2 -- 游戏进行中
extern struct Weapon* g_pMyTank;
extern int iMap[11][13];
extern bool g_bStart; // 控制一局游戏开始true与结束false
extern float g_fGameTime; // 一局游戏的剩余时间
extern int g_iScore; // 一局游戏得分
#endif//_LIST_H_

求问这要怎么办?

1个回答

你的函数存在重复定义。造成这个问题的原因有很多。
主要是你的头文件是否重复包含了

一般是
    #ifndefine  XXX_H
    #define XXX_H
    在这里写你.h本来的内容
    #endif

还有就是是否多个模块有重名的函数和变量,或者你没有使用extern关键字。

Kiniu
Kiniu 解决了,感谢指导!
7 个月之前 回复
Kiniu
Kiniu 我把代码贴上去了,能看一下哪里错了吗谢大神
7 个月之前 回复
caozhy
贵阳老马马善福专业维修游泳池堵漏防水工程 回复Kiniu: 变量也是一样
7 个月之前 回复
Kiniu
Kiniu 可是我是a里面定义的变量在a里面用报错了
7 个月之前 回复
caozhy
贵阳老马马善福专业维修游泳池堵漏防水工程 回复Kiniu: 就是在a里面定义的函数,void xxx(); 那么在b里面用,要加extern,extern void xxx();
7 个月之前 回复
Kiniu
Kiniu 我加了那个头文件卫士了还是会报错,好像也没有重复变量,请问那个extern关键字是怎么回事?
7 个月之前 回复
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问