在多个 .c 源中使用 header 个文件
using header files in multiple .c sources
在我的 CLion 项目中,我有一些 header。其中之一是 constants.h
我把我所有的常量都放在里面。现在,我想在 main.c
和 view.h
中使用这个 header。 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.c
和 view.h
中都包含它给我错误。无论如何要解决这个问题?请注意,如果我不将其包含在 view.h 中,它不会识别某些使用 constants.h
中定义的常量的部分。我需要在其他几个 .h
文件中使用这个常量。
在 main.c
和 view.h
的顶部我有:#include<constants.h>
并且我在 view.c
的顶部有 #include<view.h>
。 view.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
我是标准编程的新手,不知道如何处理。
问题是您的 header 没有定义常量,它定义了 (read-only) 个变量。您收到错误是因为 #include
将 header 的内容复制到包含它的每个源文件中,因此每个源文件都试图定义这些全局变量。
当您需要全局变量时,通常的解决方案是仅将声明放在 header 文件中:
// 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
的实际整数常量;不幸的是,这种技术不能用于 floating-point 个数字。
在我的 CLion 项目中,我有一些 header。其中之一是 constants.h
我把我所有的常量都放在里面。现在,我想在 main.c
和 view.h
中使用这个 header。 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.c
和 view.h
中都包含它给我错误。无论如何要解决这个问题?请注意,如果我不将其包含在 view.h 中,它不会识别某些使用 constants.h
中定义的常量的部分。我需要在其他几个 .h
文件中使用这个常量。
在 main.c
和 view.h
的顶部我有:#include<constants.h>
并且我在 view.c
的顶部有 #include<view.h>
。 view.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
我是标准编程的新手,不知道如何处理。
问题是您的 header 没有定义常量,它定义了 (read-only) 个变量。您收到错误是因为 #include
将 header 的内容复制到包含它的每个源文件中,因此每个源文件都试图定义这些全局变量。
当您需要全局变量时,通常的解决方案是仅将声明放在 header 文件中:
// 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
的实际整数常量;不幸的是,这种技术不能用于 floating-point 个数字。