2012-07-31 67 views
0

我正在做C编程任务,但我很困惑如何组织它。我应该如何组织这个C项目

所以,这里是情况。我有两个树实现,并在两个单独的头文件中声明它们的struct/includes/function prototypes等等。然后我有两个c源代码的两个实现。现在问题来了。对于树的ADT,我有一个测试c文件(仅用于运行测试的一个主要功能)。由于这两个实现将使用相同的测试。我怎样才能避免做同一个main.c文件的两个副本?当我包含树实现的头文件1时,我可以做gcc Tree_implementation1.c main.c。但要执行implementation2,我必须回到主源文件并手动将include包括到树实现2中,然后我可以使用相同的编译命令。我该如何解决这个问题,以便只用一个main.c切换两个实现?

+0

出于好奇,为什么你还要标记这个C++? – 2012-07-31 17:14:34

+0

我在我的数据结构类中,我们使用的这本书非常古老。那时候,他们没有OOP。所以大多数接口都是使用Pascal在函数中实现的。我主要用C实现了这些,但我还包含了一些方便的C++类,如字符串,流和东西。因此,我也用C++标记了它。 :) – zsljulius 2012-08-01 01:28:37

回答

1

使用预处理和恒定的,你可以在命令行设置:

在你的main.c:

#ifdef TREE_IMPL1 
#include "TreeImplementation1.h" 
#else 
#include "TreeImplementation2.h" 
#endif 

// ... 

int main(int argc, char **argv) 
{ 
#ifdef TREE_IMPL1 
    // code for testing TreeImplementation1 
#else 
    // code for testing TreeImplementation2 
#endif 
} 

当您编译,或者通过在命令行上省略TREE_IMPL1,或者将其设置在您的IDE中:

gcc -DTREE_IMPL1 main.c ... 
+0

这太棒了! gcc中有很多选项需要学习。谢谢你的帮助! – zsljulius 2012-07-31 17:09:54

1

您的实现是否具有相同的名称?他们不应该。

如果(或何时)它们不具有相同的名称,则只需在main.c中包含两个标头,然后根据某个预处理器指令测试其中一个标头。

//main.c 
#include "Tree_implementation1.h" 
#include "Tree_implementation2.h" 

int main() 
{ 
#ifdef TEST_FIRST 
    testFirstTree(); //declared in Tree_implementation1.h 
#else 
    testSecondTree(); //declared in Tree_implementation2.h 
#endif 
    return 0; 
} 
+0

我认为你的想法与上述基本相同。感谢您的帮助。 – zsljulius 2012-07-31 17:10:51

+0

@zsljulius esentially,是的,但我建议你包括这两个文件。这样,潜在的命名冲突就会出现。 – 2012-07-31 17:11:44

1

您的问题的另一种解决方案是使用动态接口。 按照这样的方式工作:

#include "Imp_1.h" 
#include "Imp_2.h" 

typedef void (*TreeFunctionType1)(Tree,param); 
typedef void (*TreeFunctionType2)(Tree); 

typedef struct ITree 
{ 
    TreeFunctionType1 func1; 
    TreeFunctionType2 func2; 
}ITree; 

static ITree _Itree={0}; 

void SetImp(TreeFunctionType1 f1,TreeFunctionType2 f2) 
{ 
    tree.func1 = f1; 
    tree.func2 = f2; 
} 

/*Use only this functions in your Tests code*/ 
//{ 
void Func1(Tree tree,Param param) 
{ 
    (*_Itree.func1)(tree,param); 
} 

void Func2(Tree tree) 
{ 
    (*_Itree.func2)(tree); 
} 
//} 

int main(int argc, char const *argv[]) 
{ 
    SetImp(Imp_1_f1,Imp_1_f2); 
    TestCode(); 
    SetImp(Imp_2_f1,Imp_2_f2); 
    TestCode(); 
    return 0; 
}