2013-08-02 2 views
0

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

  • определения типов, основного() и другие функции
  • Объявления переменного (чье определение типа находится в указанном файле) и функция для работы с этими переменными

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

Я пробовал использовать заявления «включить» и «внешний», но не очень удался. Поскольку два файла получают информацию друг от друга, было бы более полезно разбить их на три файла следующим образом?

1) Тип определения

2) Объявления переменных (с использованием типов, определенных в файле 1) и функции, связанные с

3) Main(), а остальные функции, которые используют две вышеуказанные файлы

Если бы это был путь, как бы это работало? Будет ли он использовать include или extern, и как мне нужно будет использовать эти предложения?

Любая помощь, которую вы можете предоставить, очень ценится. Спасибо!

+0

Добро пожаловать в Переполнение стека. Вскоре прочитайте страницу [О программе]. Звучит так, как будто вам нужен заголовочный файл, содержащий описания типов, которые будут включены кодом, содержащим 'main()' и т. Д., А также сгенерированным кодом (более или менее коварными средствами). Сколько у вас контроля над тем, что генерируется? Сгенерированный код включает в себя любой заголовок, который вы контролируете? –

+0

Возможно, пример двух файлов и тип файлов помогут вам получить требуемое решение здесь. –

+0

Привет, Джонатан, спасибо за ваш ответ. Я контролирую весь код, включая заголовки и остальную часть кода в сгенерированном файле. Я получу соответствующий код из каждого из файлов и опубликую его. Спасибо за быстрый ответ! – Irina

ответ

1

Нет ничего плохого в планировке, которую вы предлагаете. Возможно, некоторое разъяснение о том, что extern и #include do было бы полезно. 1) #include директива препроцессора, которая по существу говорит: `взять указанный файл и делать вид, что наклеена вместо этой директивы»

2) ехЬегп является C зарезервированное слово. Не вдаваться в слишком много технических вопросов, но его смысл: «переменная, указанная в этом выражении, определена в другом месте». Пространство для переменной зарезервировано компилятором ровно один раз, поэтому, если функция нуждается в доступе к рассматриваемой переменной, некоторая информация необходима до того, как определение увидит компилятор.Объявление extern содержит достаточно информации о функции, использующей переменную, и компоновщик гарантирует, что правильная переменная будет использоваться на более позднем этапе.

Таким образом, в вашем сценарии файл с определениями типов будет #include 'd в каждом файле, который относится к этим типам. Если вы хотите собрать все определения переменных в одном файле, которые будут скомпилированы отдельно от других частей вашего проекта, для любого файла, который использует эти переменные и который будет скомпилирован отдельно, необходимо предоставить объявление extern для каждой переменной, определенной в другом месте. Обратите внимание, что если вы просто включаете файл th с определениями переменных, компилятор дважды увидит определение (сначала в файле с определениями, затем в файле, который включает его), и предположим, что вы пытаетесь определить каждую переменную дважды и выпустите ошибка.

Наконец, вот простой сценарий (это на самом деле не имеет смысла, и в плохом стиле):

ас ---------

#include "t.h" 

mytype a; 
mytype b; 

int f(int x, int y) { 

    return (x + y)*a - b; 

} 

MC --- ------

#include <stdio.h> // for stdout 
#include "t.h" 
#include "v.h" 

int main() { 

    fprintf(stdout, "%d", a + b - f(1, 2)); 

    return 0; 

} 

й -----------

typedef int mytype; 

v.h -----------

#include "t.h" 

extern mytype a, b; 

int f(int, int); 

v.h и t.h могут быть объединены (это вопрос стиля и требования к проекту). Обратите внимание, что объявление f в v.h имеет подразумеваемый extern перед ним.

+0

Алекс, это фантастическая информация. Я отделил свой код, как вы упомянули, и, похоже, проблема. Когда я компилирую два .c-файла, он сообщает мне, что у меня есть необъявленные переменные в mc. В принципе, он не видит переменные, которые я объявлял в ac (хотя я их компилирую, используя «gcc ac mc». Что я могу делать неправильно? Я не вижу ссылок на ac в mc выше, так что mc все еще должен быть способен видеть содержимое ac каким-то образом? Большое спасибо! – Irina

+0

Я только что попробовал, и он скомпилирован просто отлично. возможно, опубликует сообщение об ошибке gcc производит? Также попытайтесь скомпилировать их отдельно, как в 'gcc -c ac' и' gcc -c mc', и посмотреть, что произойдет. Также вы убедились, что vh и th находятся в одном каталоге? Информация переменной mc требуется из этих файлов заголовков. Я изменил одну опечатку, хотя: printf должен был быть fprintf – alexsh

0

Как указано в комментарии, вам почти наверняка понадобится заголовок - назовите его header.h - который будет включен в файл, содержащий основную программу (файл 1, назовите ее main.c) и в сгенерированном файле (файл 2 , назовите его generated.c).

В заголовочном файле будут содержаться описания типов и объявления общих функций (а также уничтожить мысли, декларации для любых глобальных переменных). Он будет самодостаточным и идемпотентным (см., Среди прочих, вопросы переполнения стека What are extern variables in C?, Should I use #include in headers?, How to link multiple implementation files in C? и Linking against a static library).

Оба main.c и generated.c будут включать header.h. Чтобы гарантировать, что header.h является автономным, один (или оба) файлов будет #include "header.h" в качестве первого заголовка.

0

И наконец исправлено. Если у кого-то еще есть такая же проблема, я последовал за Alexsh'ами, но мне также пришлось include guards в моих .h файлах, чтобы предотвратить переопределение (иначе оно не будет компилироваться). Большое спасибо и Алексу, и Джонатану за помощь!

+0

Я не видел этого, когда оставил свой комментарий раньше. Рад, что все это сработало. – alexsh