如何有效地构建C程序

时间:2009-06-07 12:08:10

标签: c

首先我要说的是,我在C和C ++方面都有相当多的经验。但是,我正在用C开始一个新项目,我一直在使用面向对象的语言很长时间(C#和C ++),我无法想出一种以过程语言封装功能的有效方法。我的第一个想法是简单地依靠我的OO知识并将其结构化为:

struct Foo 
{
    int x;
    char *y;
}; 

struct Foo *new_Foo()
{
    return (struct Foo *)malloc(sizeof(struct Foo));
} 

void Foo_member_function(struct Foo *foo, int z)
{
    foo->x = z;    
}

但这似乎很乏味,与C的精神相反。更不用说它是一个穷人的OO。

这个程序最终会变得相当大,所以从一个好的设计组织开始是至关重要的。我想,随着C语言的多年发展,某些设计模式已经发展到如何最好地构建代码以实现可维护性。与函数式编程非常相似,我希望过程式编程具有干净且可读性的范例。

相关文章和书籍的指示也是可以接受的。

7 个答案:

答案 0 :(得分:16)

这是一种非常正常和明智的做法。但是尽量不要在头文件中公开struct layout,这样你就可以更灵活地实现它并更好地管理你的依赖项。

有关详细信息,请参阅Opaque pointer

答案 1 :(得分:12)

你所建议的是我在做这样事情的那些日子里总是写C程序的方式。我不认为这是“穷人的OO”,我认为这是合理的程序编程实践。

我会观察一些关于你的C代码的事情:

  • 使用带有结构定义的typedef,因此您无需在整个代码中分散'struct'关键字
  • 仅在实际需要时使用强制转换 - 来自malloc()的返回值的强制转换是不必要的

答案 2 :(得分:3)

嗯...我们以前只使用命名约定...... Ergo:str *用什么常见的数据结构做什么?所以也许只需要使用C#语法和s /./_/ g?

  • foo_constructor
  • foo_destructor
  • foo_someMethod
  • foo_someMethod2 //在ANSI C中没有重载
  • foo_otherMethod

......并且没有继承......

  • foo2_constructor
  • foo2_destructor
  • foo2_someMethod //并且没有多态性

但是看看光明的一面......你可以使用指向指针指向函数的指针返回指针指向指针int!哦,快乐!

我最好的建议是学习Java的经验教训(并通过推理C#)并构建你的库以避免副作用...更多typdefs ==少头疼......如果你的工作如何遵循这位圣人建议请告诉我; - )

干杯。基思。

答案 3 :(得分:3)

这是编写C程序的一种非常合理的方法。还有另一个大型应用程序,它的功能几乎相同 - 称为Linux内核。在那里使用了一些近乎OO的特征:

  • 用于封装的结构的结构和操作就像在您的示例中一样
  • 指向基础结构作为穷人遗产的一种形式 - 你会发现很多 在那里引用struct kobject
  • 宏生成函数以替代模板编程

答案 4 :(得分:1)

C是一种低级语言,在这方面,根据代码函数和模块组织数据结构非常有用。

我建议您在任何想要创建数据对象的地方使用typedef和枚举。使用宏或静态函数根据需要初始化,分配和“销毁”。

答案 5 :(得分:1)

我同意上述建议。你正在以最好的方式做到这一点..如果你想用C编程。

当然,您可以编写一个预处理器来为您自动生成这些声明和事物..也许使用“类”声明...将您想要成为函数的函数放在类中...等等。

但我们在这里得到的是一个简单的C ++到C编译器。为什么不用C ++编程,使用真正的C ++编译器,使用干净的接口,只需将C ++代码与C代码链接起来?你需要在C和C ++中编码的原因是什么?或者如果需要,从编译器生成C代码并将输出C代码与您需要的任何其他代码一起编译。

答案 6 :(得分:0)

我已经在一个项目上工作了一段时间,库需要在C中,但我希望有一些形式的OO功能。我正在做一些与此类似的事情。更多细节。

struct klass {
  char * value;

  void (*set_value) (struct klass *, const char *);
  void (*destroy) (struct klass *);
};

static void
klass_method_set_value (struct klass * k, const char * value) {
  if (k->value == NULL) {
  }
}

static void 
klass_object_desetroy (struct klass * k) {
  free (k);
  k = NULL;
}

static void
klass_method_destroy (struct klass * k) {
  klass_object_destroy (k);
}

static struct klass *
klass_object_init (void) {
  struct klass * obj = (struct klass *) malloc (sizeof (struct klass*) );

  /* members */
  obj->value = NULL;

  /* methods */
  obj->set_value = klass_method_set_value;
  obj->destroy = klass_method_destroy;
  return obj;
}

struct klass * 
klass_new (void) {
  return klass_object_init ();
}

如果出现问题,请原谅我;写得快一点。