Преодоление ограничений C для крупных проектов
Один аспект, где C показывает, что его возраст - это инкапсуляция кода. Многие современные языки имеют классы, пространства имен, пакеты... гораздо удобнее организовать код, чем просто "включить".
Так как C по-прежнему является основным языком для многих крупных проектов. Как вы можете преодолеть свои ограничения?
Я полагаю, что одним главным фактором должно быть множество дисциплины. Я хотел бы знать, что вы делаете для обработки большого количества кода C, какие авторы или книги вы можете порекомендовать.
Ответы
Ответ 1
- Отделите код на функциональные блоки.
- Постройте эти единицы кода в отдельные библиотеки.
- Используйте скрытые символы в библиотеках, чтобы уменьшить конфликты пространства имен.
Подумайте об открытом исходном коде. В ядре Linux имеется огромное количество кода C, библиотека GNU C, система X Window и рабочий проект Gnome. Тем не менее, все работает вместе. Это связано с тем, что большая часть кода не видит другого кода. Он обменивается только четко определенными интерфейсами. Сделайте то же самое в любом крупном проекте.
Ответ 2
Некоторым людям это не нравится, но я сторонник организации моих структур и связанных функций вместе, как если бы они были классом, в котором этот указатель передается явно. Например, в сочетании с последовательным соглашением об именах, чтобы сделать пространство имен явным. Заголовок будет выглядеть примерно так:
typedef struct foo {
int x;
double y;
} FOO_T
FOO_T * foo_new();
int foo_set_x(FOO_T * self, int arg1);
int foo_do_bar(FOO_T * self, int arg1);
FOO_T * foo_delete(FOO_T * self);
В реализации все функции "private" будут статическими. Недостатком этого является то, что вы не можете фактически обеспечить, чтобы пользователь не пошел и не сработал с членами структуры. Это просто жизнь в c. Я нахожу этот стиль, хотя и делает для хорошо повторяющихся типов C.
Ответ 3
Хорошим способом достижения некоторой инкапсуляции является объявление внутренних методов или переменных модуля как static
Ответ 4
Как говорит Андрес, static
- ваш друг. Но говоря о друзьях... если вы хотите разделить библиотеку в двух файлах, то некоторые символы из одного файла, которые должны быть замечены в другом, не могут быть static
.
Решите некоторые соглашения об именах: все нестатические символы из библиотеки foo
начинаются с foo_
. И убедитесь, что они всегда соблюдаются: это именно те символы, для которых он кажется ограниченным ( "Мне нужно называть его foo_max
?! Но это просто max
!" ), Что будут столкновения.
Как говорит Зан, типичный дистрибутив Linux можно рассматривать как огромный проект, написанный в основном на C. Он работает. Существуют интерфейсы, а крупные подпроекты реализованы как отдельные процессы. Реализация в отдельных процессах помогает отлаживать, тестировать, повторно использовать код и обеспечивает вторую иерархию в дополнение к единственной, которая существует на уровне ссылки. Когда ваш проект станет достаточно большим, может возникнуть смысл поместить некоторые функции в отдельные процессы. Что-то уже специализированное как компилятор C, как правило, реализуется как три процесса: предварительный процессор, компилятор, ассемблер.
Ответ 5
Если вы можете управлять проектом (например, внутри компании или платить кому-то другому), вы можете просто установить правила и использовать обзоры и инструменты для их принудительного применения. Для этого языка не требуется настоящая необходимость, вы можете, например, потребовать, чтобы все функции, используемые вне модуля (= набор файлов, даже не обязательно должны быть отдельными), должны быть отмечены таким образом. Фактически, вы заставите разработчиков подумать об интерфейсах и придерживаться их.
Если вы действительно хотите сделать это, вы также можете определить макросы, чтобы показать это, например.
#define PUBLIC
#define PRIVATE static
или некоторые такие.
Итак, вы правы, дисциплина - это ключ здесь. Это включает в себя установку правил и обеспечение их соблюдения.