Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/55.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
我应该如何用C构建复杂的项目?_C_Project Management - Fatal编程技术网

我应该如何用C构建复杂的项目?

我应该如何用C构建复杂的项目?,c,project-management,C,Project Management,我只具备初级C技能,我想知道是否有任何事实上的“标准”来用C构建一个稍微复杂的应用程序,甚至是基于GUI的应用程序 我一直在Java和PHP中使用OO范式,现在我想学习C,我担心我的应用程序可能会以错误的方式构造。我不知道应该遵循哪些准则来实现程序语言的模块化、解耦和干涸 你有什么建议吗?我找不到任何适用于C的应用程序框架,即使我不使用框架,我也总能通过浏览它们的代码找到好主意。我建议您查看任何流行的开源C项目的代码,比如。。。隐马尔可夫模型。。。Linux内核或Git;看看他们是如何组织的。复

我只具备初级C技能,我想知道是否有任何事实上的“标准”来用C构建一个稍微复杂的应用程序,甚至是基于GUI的应用程序

我一直在Java和PHP中使用OO范式,现在我想学习C,我担心我的应用程序可能会以错误的方式构造。我不知道应该遵循哪些准则来实现程序语言的模块化、解耦和干涸


你有什么建议吗?我找不到任何适用于C的应用程序框架,即使我不使用框架,我也总能通过浏览它们的代码找到好主意。

我建议您查看任何流行的开源C项目的代码,比如。。。隐马尔可夫模型。。。Linux内核或Git;看看他们是如何组织的。

复杂应用程序的数字规则:应该很容易阅读


为了使复杂的应用程序更简单,我采用了。

关键是模块化。这更易于设计、实现、编译和维护

  • 识别应用程序中的模块,比如OO应用程序中的类
  • 将每个模块的接口和实现分开,只将其他模块需要的内容放入接口中。请记住,C中没有名称空间,因此必须使接口中的所有内容都是唯一的(例如,带有前缀)
  • 在实现中隐藏全局变量,并使用访问器函数进行读/写操作
  • 不要从继承的角度思考,而是从构成的角度思考。一般来说,不要试图在C中模拟C++,这将是非常困难的阅读和维护。
如果您有时间学习,请查看Ada应用程序的结构,以及其必需的
(模块接口)和
包体
(模块实现)

这是用来编码的


对于维护(请记住,您只编写了一次代码,但维护了几次),我建议记录您的代码;对我来说是个不错的选择。我还建议构建一个强大的回归测试套件,它允许您进行重构。

这些测试经过几十年的发展。读一读是个好主意,即使你没有完全按照它们来做。思考其中提出的要点可以为您构建自己的代码提供更坚实的基础。

对于OO技术不能应用于C语言,这是一种常见的误解。大多数都可以——只是它们比语法专用于此的语言稍微笨拙一些

健壮系统设计的基础之一是在接口后面封装实现
FILE*
及其相关函数(
fopen()
fread()
等)是如何在C中应用封装来建立接口的一个很好的例子。(当然,由于C缺乏访问说明符,您不能强制要求没有人窥视结构文件,但只有受虐狂才会这样做。)

如有必要,可以使用函数指针表在C中实现多态行为。是的,语法很难看,但效果与虚拟函数相同:

struct IAnimal {
    int (*eat)(int food);
    int (*sleep)(int secs);
};

/* "Subclass"/"implement" IAnimal, relying on C's guaranteed equivalence
 * of memory layouts */
struct Cat {
    struct IAnimal _base;
    int (*meow)(void);
};

int cat_eat(int food) { ... }
int cat_sleep(int secs) { ... }
int cat_meow(void) { ... }

/* "Constructor" */
struct Cat* CreateACat(void) {
    struct Cat* x = (struct Cat*) malloc(sizeof (struct Cat));
    x->_base.eat = cat_eat;
    x->_base.sleep = cat_sleep;
    x->meow = cat_meow;
    return x;
}

struct IAnimal* pa = CreateACat();
pa->eat(42);                       /* Calls cat_eat() */

((struct Cat*) pa)->meow();        /* "Downcast" */

<>如果你知道如何用java或C++来构造代码,那么你可以遵循C代码的相同原理。唯一的区别是,你没有编译器在你身边,你需要额外小心地手工做每件事

因为没有包和类,所以您需要从仔细设计模块开始。最常见的方法是为每个模块创建一个单独的源文件夹。您需要依赖命名约定来区分不同模块之间的代码。例如,在所有函数前面加上模块名称

不能用C来创建类,但可以轻松实现“抽象数据类型”。为每个抽象数据类型创建一个.C和.H文件。如果您愿意,您可以有两个头文件,一个公共头文件和一个私有头文件。其思想是,所有需要导出的结构、常量和函数都将被导出到公共头文件中


你的工具也很重要。C语言的一个有用工具是,它可以帮助您发现代码中的异味。您可以使用的另一个工具是Doxygen,它可以帮助您生成。无论使用何种开发语言,封装始终是成功开发的关键

我用来帮助在C中封装“private”方法的一个技巧是不将它们的原型包含在“.h”文件中。

都是好答案

我只想添加“最小化数据结构”。在C中,这可能更容易,因为如果C++是“C类”,OOP试图鼓励你把你头上的每个名词/动词都变成一个类/方法。这可能是非常浪费的

例如,假设您有一组时间点的温度读数,并且希望在Windows中将其显示为折线图。Windows有一条绘制消息,当您收到该消息时,您可以使用LineTo函数在数组中循环,在将数据转换为像素坐标时缩放数据

我已经看过太多次了,因为图表由点和线组成,人们会建立一个由点对象和线对象组成的数据结构,每个对象都可以自己绘制,然后根据某种程度上“更有效”的理论,或者他们可能,只是可能,必须能够将鼠标移到图表的某些部分并以数字方式显示数据,因此他们在对象中构建方法来处理这些数据,当然,这涉及到创建和删除更多的对象

因此,您最终会得到大量可读性很强的代码,并且只花费90%的时间来管理对象

所有这些都是以“良好编程实践”和“效率”的名义完成的


至少在C语言中,简单、高效的方法会更加明显,构建金字塔的诱惑也会减弱。

我建议首先阅读C/C++教科书。例如,C素数