Организация файлов C

28
задан Community 23 May 2017 в 12:02
поделиться

8 ответов

Необходимо рассматривать.h файлы как [1 111] интерфейсные файлы из.c файла. Каждый.c файл представляет модуль с определенным количеством функциональности. Если функции в.c файле используются другими модулями (т.е. другие.c файлы) помещает прототипа функции в файл интерфейса.h. Включением интерфейсного файла в Ваших исходных модулях.c файл и любой.c файл Вам нужна функция в, Вы делаете эту функцию доступной для других модулей.

, Если Вам только нужна функция в определенном.c файле (не в каком-либо другом модуле), объявите его статичный объем. Это означает, что это можно только назвать из c файла, в котором это определяется.

То же идет для переменных, которые используются через несколько модулей. Они должны войти в заголовочный файл, и там у них есть к отмеченному с ключевым словом 'экстерн'.Примечание: Для функций ключевое слово 'экстерн' является дополнительным. Функции всегда считают 'экстерном'.

защита включения в заголовочных файлах помогает не включать тот же заголовочный файл многократно.

, Например:

Module1.c:

    #include "Module1.h"

    static void MyLocalFunction(void);
    static unsigned int MyLocalVariable;    
    unsigned int MyExternVariable;

    void MyExternFunction(void)
    {
        MyLocalVariable = 1u;       

        /* Do something */

        MyLocalFunction();
    }

    static void MyLocalFunction(void)
    {
      /* Do something */

      MyExternVariable = 2u;
    }

Module1.h:

    #ifndef __MODULE1.H
    #define __MODULE1.H

    extern unsigned int MyExternVariable;

    void MyExternFunction(void);      

    #endif

Module2.c

    #include "Module.1.h"

    static void MyLocalFunction(void);

    static void MyLocalFunction(void)
    {
      MyExternVariable = 1u;
      MyExternFunction();
    }
35
ответ дан Michael Potter 28 November 2019 в 02:50
поделиться

Попытайтесь заставить каждый.c сфокусироваться на конкретной области функциональности. Используйте соответствующий.h файл для объявления тех функций.

Каждый.h файл должен иметь защиту 'заголовка' вокруг, это довольно. Например:

#ifndef ACCOUNTS_H
#define ACCOUNTS_H
....
#endif

Тот способ, которым можно включать "accounts.h" так много раз, как Вы хотите, и в первый раз, это замечено в конкретной единице компиляции, будет единственный, который на самом деле вытягивает в его содержании.

10
ответ дан Andrew 28 November 2019 в 02:50
поделиться

Компилятор

Вы видите пример 'модуля' C в эта тема - Примечание, что существует два файла - заголовок tea.h и код tea.c. Вы объявляете, что вся общественность определяет, переменные и прототипы функции, что Вы хотите другие программы к доступу в заголовке. В Вашем основном проекте Вы будете, #include и тот код могут теперь получить доступ к функциям и переменным модуля чая, которые упоминаются в заголовке.

Это становится немного более сложным после этого. Если Вы используете Visual Studio и много других IDE, которые управляют Вашей сборкой для Вас, то игнорируют эту часть - они заботятся о компиляции и соединении объектов.

Компоновщик

при компиляции двух отдельных файлов C компилятор производит файлы отдельного объекта - таким образом, main.c становится main.o, и tea.c становится tea.o. Задание компоновщика должно посмотреть на все объектные файлы (Ваш main.o и tea.o), и подойти ссылки - поэтому, когда Вы вызываете функцию чая в основном, компоновщик изменяет тот вызов, таким образом, это на самом деле вызывает правильную функцию в чае. Компоновщик производит исполняемый файл.

существует большое учебное руководство , которое входит в большую глубину на этом предмете, включая объем и другую проблему, с которой Вы столкнетесь.

Удачи!

-Adam

7
ответ дан Community 28 November 2019 в 02:50
поделиться

Несколько простых правил запуститься:

  1. Помещенный те объявления, что Вы хотите обнародовать в заголовочный файл для файла реализации C, который Вы создаете.
  2. Только #include заголовочные файлы в файле C, которые необходимы для реализации файла C.
  3. включают заголовочные файлы в заголовочный файл только если необходимый для объявлений в том заголовочном файле.

  4. Использование включать защитный метод, описанный Andrew ИЛИ, использует #pragma однажды , если компилятор поддерживает его (который делает то же самое - иногда более эффективно)
7
ответ дан denis phillips 28 November 2019 в 02:50
поделиться

Отвечать на Ваш дополнительный вопрос:

Этот вопрос ускорил мой запрос. tea.h файл не делает ссылки на tea.c файл. Компилятор "Знает", что каждый.h файл имеет соответствующий.c файл?

компилятор, прежде всего, не касается заголовочных файлов. Каждый вызов компилятора компилирует источник (.c) файл в объект (.o) файл. Негласно (т.е. в make файл или файл проекта) командная строка, эквивалентная этому, сгенерирована:

compiler --options tea.c

исходный файл #include с все заголовочные файлы для ресурсов, на которые это ссылается, который является, как компилятор находит заголовочные файлы.

(я заминаю некоторые детали здесь. Существует много для приобретения знаний о создании C проектов.)

3
ответ дан Community 28 November 2019 в 02:50
поделиться

А также ответы предоставили выше, одно небольшое преимущество накладывания шины Ваш код в модули (отдельные файлы) - то, что, если у Вас должны быть какие-либо глобальные переменные, можно ограничить их объем единственным модулем при помощи ключевого слова 'статичный'. (Вы могли также применить это к функциям). Обратите внимание, что это использование 'статических' отличается от своего использования в функции.

3
ответ дан David L Morris 28 November 2019 в 02:50
поделиться

Ваш вопрос проясняет, что Вы действительно не сделали большой серьезной разработки. Обычный случай - то, что Ваш код обычно будет слишком большим для вписывания в один файл. Хорошее правило состоит в том, что необходимо разделить функциональность на логические единицы (.c файлы), и каждый файл должен содержать не больше, чем, что можно легко держать в голове когда-то.

А, данный программный продукт тогда обычно, включает вывод из многих различных.c файлов. То, как это обычно делается, - то, что компилятор производит много объектных файлов (в системах Unix ".o" файлы, VC генерирует .obj файлы). Это - цель "компоновщика" составить эти объектные файлы в вывод (или общая библиотека или исполняемый файл).

Обычно Ваша реализация (.c) файлы содержит фактический исполняемый код, в то время как заголовочные файлы (.h) имеют объявления государственных функций в тех файлах реализации. У Вас может довольно легко быть больше заголовочных файлов, чем существуют файлы реализации, и иногда заголовочные файлы могут содержать встроенный код также.

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

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

1
ответ дан 1800 INFORMATION 28 November 2019 в 02:50
поделиться

.h файлы должны использоваться для определения прототипов для функций. Это необходимо, таким образом, можно включать прототипы, в которых Вы нуждаетесь в своем C-файле, не объявляя каждую функцию, что Вам нужны все в одном файле.

, Например, когда Вы #include <stdio.h>, это обеспечивает прототипы для printf и других функций IO. Символы для этих функций обычно загружаются компилятором по умолчанию. Можно посмотреть на.h файлы системы под/usr/include, если Вы интересуетесь нормальными идиомами, связанными с этими файлами.

, Если Вы только пишете тривиальные приложения с не много функций, не действительно необходимо построить все из модулей в логические группировки процедур. Однако, если у Вас будет потребность разработать большую систему, тогда необходимо будет уделить некоторое внимание как, туда, где определить каждую из функций.

0
ответ дан hoyhoy 28 November 2019 в 02:50
поделиться
Другие вопросы по тегам:

Похожие вопросы: