在多个.c源文件中使用头文件

时间:2018-12-22 15:37:39

标签: c header-files

在CLion中的项目中,我有一些标题。其中之一是constants.h,我将所有常量都放入其中。现在,我想在main.cview.h中使用此标头。 view.c是与view.h关联的另一个源文件。每当我使用它时,由于常量的重新定义,都会产生错误。我还用过:

//constants.h
#ifndef PROJECT_CONSTANTS_H
#define PROJECT_CONSTANTS_H
# define pi 3.14159265359
# define degToRad (2.000*pi)/180.000

//GAME GRAPHICS CONSTANTS
const int TANK_RADIUS = 15;
const int CANNON_LENGTH = TANK_RADIUS;
const int BULLET_RADIUS = 4;
const int BULLET_SPAWN_POS = TANK_RADIUS+BULLET_RADIUS;
//const int tank_width = 10;
//const int tank_height = 20;
const int WIDTH = 800;
const int HEIGHT = 600;

//GAME LOGICAL CONSTANTS
const int step = 5;
const double angleStep = 4.5;
const int bulletSpeed = 8;
#define maxBulletPerTank  10
#endif

//main.c includes
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
#include <SDL.h>
#include <SDL2_gfxPrimitives.h>
#include "structs.h"


#include "view.h"

//view.h
#ifndef PROJECT_VIEW_H
#define PROJECT_VIEW_H

#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
#include <SDL.h>
#include <SDL2_gfxPrimitives.h>
#include "constants.h"


SDL_Renderer* init_windows(int width , int height);

#endif

//view.c

#include "view.h"
SDL_Renderer* init_windows(int width , int height)
{
    SDL_Init(SDL_INIT_VIDEO);
    SDL_Window* window = SDL_CreateWindow("workshop", 100, 120, width, height, SDL_WINDOW_OPENGL);
    SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
    return renderer;
}

在constants.h的第一部分,但同时将其包含在main.cview.h中给了我错误。反正有解决办法吗?请注意,如果我没有在view.h中包含它,它就无法识别某些使用constants.h中定义的常量的部分。我需要在其他几个.h文件中使用此常量。

main.cview.h顶部的

我有:#include<constants.h>,在#include<view.h>顶部有view.cview.h顶部也包含main.c

错误之一:

CMakeFiles\project_name.dir/objects.a(view.c.obj):[address]/constants.h:26: multiple definition of `step':
CMakeFiles\project_name.dir/objects.a(main.c.obj):[address]/constants.h:23: first defined here

我是标准编程的新手,不知道如何处理。

1 个答案:

答案 0 :(得分:0)

问题在于您的标头没有定义常量,而是定义了(只读)变量。由于#include将标头的内容复制到包含该标头的每个源文件中,因此每个源文件都试图定义这些全局变量,因此会出现错误。

想要全局变量时,通常的解决方案是仅将声明放入头文件中:

// constants.h
extern const int step;
extern const double angleStep;

实际的变量定义位于(一个)源文件中:

// constants.c
#include "constants.h"
const int step = 5;
const double angleStep = 4.5;

但是请注意,这些不是常量:

switch (...) {
    case step:  // Error: case label must be a constant
        ...
}

如果要使用实际常量,则应改用宏:

// constants.h
#define STEP 5
#define ANGLE_STEP 4.5

那么您也不需要单独的.c文件。

仅对于整数常量,有一种涉及枚举的解决方法:

// constants.h
enum { step = 5 };

这将创建一个称为step的实际整数常量;不幸的是,这种技术不能用于浮点数。