Подтвердить что ты не робот

Как эффективно структурировать программу 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. Не говоря уже о том, что это плохой человек.

Эта программа в конечном итоге станет довольно значительной, поэтому очень важно создать хорошую организацию дизайна. Я полагаю, что с годами развития в C некоторые шаблоны проектирования разработали, как наилучшим образом структурировать код для ремонтопригодности. Как и функциональное программирование, я надеюсь, что процедурное программирование имеет парадигму, которая чиста и достаточно читаема.

Указатели соответствующих статей и книг также приемлемы.

4b9b3361

Ответ 1

Это довольно нормальная и разумная практика. Но постарайтесь не раскрывать структуру структуры в файлах заголовков, чтобы у вас была определенная гибкость в том, как она реализована и лучше управляет вашими зависимостями.

Подробнее см. Opaque pointer.

Ответ 2

Что вы предлагаете, так это то, как я всегда писал программы C в те дни, когда я это делал. Я не думаю, что это "бедные мужчины ОО", я думаю, что это разумная процедура процедурного программирования.

Я бы заметил пару вещей о вашем коде на C:

  • используйте typedefs с определениями struct, поэтому вам не нужно разбрасывать ключевое слово 'struct' на протяжении всего кода
  • используют только приведения, когда они на самом деле нужны, - приведение значения возвращаемого значения из malloc() не требуется

Ответ 3

Хммм... Раньше мы использовали соглашения об именах... Ergo: str * делает что-то с общей структурой данных? Так что, возможно, просто возьмите синтаксис С# и s/./_/g?

  • foo_constructor
  • foo_destructor
  • foo_someMethod
  • foo_someMethod2//не перегружает в ANSI C
  • foo_otherMethod

... и наследования нет...

  • foo2_constructor
  • foo2_destructor
  • foo2_someMethod//и нет никакого полиморфизма

Но посмотрите на яркую сторону... вы можете использовать pointer-to-pointer-to-pointer-to-function-return-a-pointer-to-pointer-int! О, радость!

Мое самое лучшее пособие - выучить уроки Java (и путем вывода С#) и структурировать ваши библиотеки, чтобы НЕ иметь побочные эффекты... больше typdefs == меньше головных болей... и если ваша разработка, как следовать этот мудрец посоветуйте, пожалуйста, дайте мне знать; -)

Приветствия. Кит.

Ответ 4

Это довольно разумный способ написать программу на C. Существует еще одно большое приложение, которое делает практически то же самое, что и ядро ​​Linux. Некоторые почти OO-функции, используемые там:

  • структуры и операции над структурами для инкапсуляции, как в вашем примере
  • указывает на базовые структуры как на вид наследования бедных людей - вы найдете множество ссылки на struct kobject там
  • макросы для генерации функций в качестве замены для программирования шаблонов

Ответ 5

C был языком низкого уровня, и в этом отношении было бы очень полезно организовать ваши структуры данных в соответствии с вашими кодовыми функциями и модулями.

Я бы предположил, что вы используете typedefs и перечисления везде, где бы вы хотели создать объекты данных. Используйте макросы или статические функции для инициализации, выделения и "уничтожения" по мере необходимости.

Ответ 6

Я согласен с приведенными выше предложениями. Вы делаете это наилучшим образом. Если вы хотите запрограммировать на C.

Конечно, вы могли бы написать предварительный процессор, чтобы автоматически генерировать эти объявления и вещи для вас.. может быть, использовать объявление "Class"... поставить функции, которые вы хотите быть функциями-членами внутри класса.. и т.д.

Но у нас есть простой компилятор С++ to C. Почему бы просто не программировать на С++, использовать настоящий компилятор С++, использовать чистые интерфейсы и просто связать код С++ с кодом C? В чем причина того, что вам нужно кодировать в C или С++? Или, если вам нужно, сгенерировать код C из компилятора и скомпилировать код вывода C вместе с тем, что вам нужно.

Ответ 7

Я работаю над проектом на некоторое время, когда библиотека должна быть на 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 ();
}

Прости меня, если что-то не так; написал это немного быстро.