【发布时间】:2017-12-09 13:48:49
【问题描述】:
我有一个 C 项目,但我真的不知道如何管理 .c 和 .h。 我多年来一直在使用一种方法,但现在我必须在没有任何警告的情况下创建代码,所以我需要改变我的做法。
这是我的做法:
每个 .c 都有一个同名的 .h。甚至 main.c 都有一个 main.h。
在每个 .c 中,我都包含匹配的 .h,因此每个 .c 我只有一个包含。 在 main.h 中,我包含了我需要的所有库,例如 stdio stdlib 等。我还在那里声明了我的枚举和结构。
最后,在其他每个 .h 中,我都包含 main.h,其中包含结构、枚举和库。
我知道这样做,我会调用 main.h 很多时间,但我在每个 .h 中都使用 #ifndef 和 #define。
此外,我每个 .h 都在其对应的 .c 中包含函数的原型
我应该如何管理 .c 和 .h?
我忘了提到问题是我对每个函数都收到警告:“函数的隐式声明”
这是一个包含四个文件的示例:
main.c:
#include "main.h"
int main()
{
// code
}
int save(Player players[2], int currentPlayer)
{
// code
}
int load(Player players[2], int* currentPlayer)
{
// code
}
main.h:
#ifndef MAIN_H
#define MAIN_H
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <windows.h>
#include <string.h>
#include <math.h>
typedef enum Direction Direction;
typedef enum Orientation Orientation;
typedef enum ShipType ShipType;
typedef enum CaseType CaseType;
typedef enum Status Status;
typedef enum PlayerType PlayerType;
enum Direction
{
Nord=0, Est=1, Sud=2, Ouest=3
};
enum Orientation
{
None=0, Horizontal=1, Vertical=2
};
enum ShipType
{
SousMarin=1, Destroyer=2, Croiseur=3, Cuirasse=4
};
enum CaseType
{
Undiscovered=0, Empty=1, Hit=2, Detected=3, Discovered=5
};
enum Status
{
Undamaged=0, Damaged=1, Drowned=2
};
enum PlayerType
{
Human=0, Computer=1
};
typedef struct Map Map;
typedef struct Ship Ship;
typedef struct Player Player;
struct Map
{
int width, height;
int* cases;
};
struct Ship
{
int x, y, length, firstShoot, color;
int hasBeenDiscovered;
Orientation orientation;
ShipType type;
Status status;
};
struct Player
{
int totalShips;
int activeShips;
Map map[2];
char lastMoves[5][128];
Ship* ships;
PlayerType type;
int shipcolor[4];
int shipNumber[4];
int color;
};
int save(Player players[2], int currentPlayer);
int load(Player players[2], int* currentPlayer);
#endif // MAIN_H
IA.c:
#include "IA.h"
int IA(Player* IA, Player* enemy)
{
// code
}
// And all my other functions
IA.h:
#ifndef IA_H
#define IA_H
#include "main.h"
int IA(Player* IA, Player* enemy);
void endIATurn(Player* IA);
int enemyShipDiscovered(Map map, int* x, int* y, int SousMarinSpecific);
Ship* bestFriendlyActiveShip(Ship* ships, int totalShips, int SousMarinSpecific);
int friendlyShipDiscovered(Ship** ship, Ship* ships, Map map, int totalShips, int SousMarinSpecific);
int hitShipButNotDrowned(Player* IA, Player enemy, int totalShips, int* x, int* y);
int hasAtLeastOneMoveableShip(Player player);
int hasUndiscoveredCases(Player player);
void getUndiscoveredCoordoonnees(Map map, int* x, int* y);
int findNextCaseToShootAt(Map map, Ship ship, int* a, int* b);
#endif // IA_H
我所有的其他 .h 都像 IA.h
【问题讨论】:
-
考虑到您处理文件的方式,我更期待一个 duplicate 声明...我们可以看看
.c及其对应的.h的摘录吗? -
而您已经收到这些警告 年 并且直到现在才考虑对此采取任何措施!?如果你有一个“隐式声明”,编译器在调用函数时看不到声明 - 不知何故你没有包含标题或标题不正确。从您的文字描述中,您在做什么还很不清楚;贴一些例子。
-
问题可能是您在
main函数中使用了其他文件中的函数,而没有包括这些文件的标题。在main.cpp中包含main.h是不够的,您需要包含包含您使用的每个函数的标题(例如,如果您的main函数使用来自foo.c的函数,则需要包含@987654335 @ 在main.c或main.h)。同样,如果你想在foo.c中使用来自bar.c的函数,你需要在foo.c中包含bar.h。 -
.h文件应该只有#include用于它直接依赖的标头。.c或.cpp文件应该包含它自己的头文件,以及它直接依赖的所有头文件。你的头文件应该有头文件保护和/或#pragma once,这取决于你的编译器。您放入main.h的所有内容我都会放入common.h,只是为了更清楚。对于较大的项目,请考虑制作 header-headers。
标签: c project header-files