Відповіді:
Якщо правильно використовувати, це може бути корисною технікою.
Скажімо, у вас складна, критична підсистема з досить невеликим загальнодоступним інтерфейсом і безліччю коду реалізації, який не використовується повторно. Код працює на кілька тисяч рядків, сто або більше приватних функцій і зовсім небагато приватних даних. Якщо ви працюєте з нетривіальними вбудованими системами, ви, ймовірно, стикаєтеся з цією ситуацією досить часто.
Ваше рішення, ймовірно, буде шаруватим, модульним і нерозв'язним, і ці аспекти можуть бути корисно представлені та посилені кодуванням різних частин підсистеми в різних файлах.
З C ви можете багато чого втратити, зробивши це. Практично всі ланцюги інструментів забезпечують гідну оптимізацію для однієї компіляційної одиниці, але дуже песимістично ставляться до всього, що оголошено зовнішнім.
Якщо ви помістите все в один вихідний модуль C, ви отримаєте -
Поліпшення продуктивності та розміру коду - виклики функцій будуть вказуватися у багатьох випадках. Навіть не вкладаючи, компілятор має можливість створити більш ефективний код.
Приховування даних рівня функцій та функцій.
Уникнення забруднення простору імен та його наслідків - ви можете використовувати менш громіздкі імена.
Швидше складання та зв’язок.
Але ви також отримуєте нечестивий безлад, коли справа доходить до редагування цього файлу, і ви втрачаєте припущену модульність. Це можна подолати, розділивши джерело на кілька файлів і включивши їх для отримання єдиного блоку компіляції.
Для правильного управління цим вам потрібно ввести деякі умови. Вони певною мірою залежатимуть від вашої ланцюжка інструментів, але деякі загальні вказівки -
Помістіть загальнодоступний інтерфейс в окремий файл заголовка - це все одно ви повинні робити.
Майте один головний .c файл, який включає всі допоміжні файли .c. Сюди також можна включити код для загальнодоступного інтерфейсу.
Використовуйте захисні засоби компілятора, щоб переконатися, що приватні заголовки та вихідні модулі не включаються до зовнішніх блоків компіляції.
Усі приватні дані та функції повинні бути оголошені статичними.
Підтримуйте концептуальне розмежування файлів .c та .h. Це використовує існуючі конвенції. Різниця полягає в тому, що у вас буде багато статичних декларацій у своїх заголовках.
Якщо ваша інструментальна мережа не нав'язує жодних причин цього не робити, називайте приватні файли реалізації як .c та .h. Якщо ви використовуєте включені охоронці, вони не створюватимуть код і не вводять нових імен (ви можете виявити деякі порожні сегменти під час посилання). Величезна перевага полягає в тому, що інші інструменти (наприклад, IDE) будуть належним чином обробляти ці файли.
це нормально? так, вона складе
це рекомендується? no - .c файли компілюються у .obj-файли, які після компіляції (через лінкер) з'єднуються у виконуваний файл (або бібліотеку), тому немає необхідності включати один .c-файл в інший. Напевно, ви, напевно, хочете зробити це - створити .h файл, у якому перераховані функції / змінні, доступні в іншому файлі .c, і включити .h файл
Немає.
Залежно від середовища побудови (ви не вказуєте), ви можете виявити, що воно працює точно так, як вам потрібно.
Однак є багато середовищ (як IDE, так і багато ручних Makefiles), які розраховують на компіляцію * .c - якщо це станеться, ви, ймовірно, отримаєте помилки в посиланнях через дублюючі символи.
Як правило, цієї практики слід уникати.
Якщо ви абсолютно повинні #include джерело (і його взагалі слід уникати), використовуйте інший файловий суфікс для цього файлу.
Я думав, що поділюсь ситуацією, коли моя команда вирішила включити .c файли. Наша архітектура значною мірою складається з модулів, які відокремлюються через систему повідомлень. Ці обробники повідомлень є загальнодоступними та закликають багато місцевих функцій статичного працівника виконувати свою роботу. Проблема виникла при спробі отримати покриття для наших тестових випадків, оскільки єдиний спосіб здійснення цього приватного коду реалізації був опосередковано через інтерфейс публічного повідомлення. Коли деякі робітники функціонують по коліна в штабелі, це виявилося кошмаром для досягнення належного покриття.
У тому числі .c файли дали нам змогу досягти гвинтика в машині, яка нам була цікава при тестуванні.
Ви можете використовувати компілятор gcc в Linux, щоб з'єднати два файли c на одному виході. Припустимо, у вас є два файли c, один - 'main.c', а інший - 'support.c'. Отже, команда зв'язати це двоє
gcc main.c support.c -o main.out
До цього два файли будуть пов'язані в один вихідний main.out Для запуску виводу буде команда
./main.out
Якщо ви використовуєте функцію main.c, яка задекларована у файлі support.c, вам слід оголосити її в основному також, використовуючи зовнішній клас зберігання.
Ви можете правильно включити .C або .CPP файли в інші вихідні файли. Залежно від вашої IDE, ви зазвичай можете запобігти подвійному зв’язку, переглянувши властивості вихідних файлів, які ви хочете включити, як правило, клацнувши правою кнопкою миші та клацнувши по властивостях, і зніміть прапорці / перевірити компіляцію / посилання / виключити з збірки або будь-який інший варіант може бути. Або ви не можете включити файл у сам проект, таким чином IDE навіть не знає, що він існує, і не намагається його скомпілювати. І за допомогою файлів ви просто просто не вкладаєте файл у нього для компіляції та зв’язування.
EDIT: Вибачте, що я зробив відповідь замість відповіді на інші відповіді :(
Мова C не забороняє такого роду #include, але отримана одиниця перекладу все ж має бути дійсною C.
Я не знаю, яку програму ви використовуєте з файлом .prj. Якщо ви використовуєте щось на кшталт "make" або Visual Studio чи будь-що інше, просто переконайтеся, що ви встановили його список файлів для компіляції без того, який неможливо скласти самостійно.
Включення файлу C в інший файл - це законно, але це не рекомендується, якщо ви точно не знаєте, чому це робите і чого намагаєтесь досягти.
Я майже впевнений, що якщо ви опублікуєте тут причину того, що за вашим запитанням спільнота знайде вам ще один більш підходящий спосіб досягти вашої мети (зверніть увагу на "майже", оскільки можливо, що це рішення з огляду на контекст ).
До речі, я пропустив другу частину питання. Якщо файл C включений в інший файл і в той же час включений в проект, ви, мабуть, зіткнетеся з проблемою дублювання символів, чому зв'язування об'єктів, тобто одна і та ж функція буде визначена двічі (якщо всі вони статичні).