2013-09-09 5 views
6

Я уже некоторое время читал о С и решил написать небольшую программу для добавления, ничего необычного. Мое понимание заголовков C является то, что они являются «интерфейсы» (например, как Java и других языках), но где вы можете также определить переменную, либо установили значения или нет ..Файлы заголовков в C

Так что я написал это:

#include <stdio.h> 
#include <stdlib.h> 
#include "sample.h" 

int main(int argc, char** argv) { 
    printf("hello World\n"); 
    add(12, 18); 
    return (EXIT_SUCCESS); 
} 

int add(int a, int b){ 
    int value = a+b; 
    printf("value = %d\n", value); 
    return 0; 
} 

Он имеет заголовочный файл, который выглядит, как например:

#ifndef SAMPLE_H_GUARD 
#define SAMPLE_H_GUARD 
int add(int a, int b); 
#endif 

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

Кроме того, много материала, который я прочитал, показывает один заголовочный файл для нескольких файлов C. где у многих проектов сегодня есть один заголовок за один c, то есть Sample.h принадлежит Sample.c и ничего больше.

Может ли кто-нибудь пролить свет на это?

Мог ли я сделать это так:

main.c

#include <stdio.h> 
#include <stdlib.h> 
#include "sample.h" 

int main(int argc, char** argv) { 
    printf("hello World\n"); 
    add(12, 18); 
    return (EXIT_SUCCESS); 
} 

add.c

#include <stdio.h> 
#include <stdlib.h> 
#include "sample.h" 
int add(int a, int b){ 
    int value = a+b; 
    printf("value = %d\n", value); 
    return 0; 
} 

sample.h

#ifndef SAMPLE_H_GUARD 
#define SAMPLE_H_GUARD 
int add(int a, int b); 
#endif 

Я верю в книгу, которую я читал: C Programming Language У них был пример калькулятора, разбитый таким образом, мой вопрос в том, как C знает, где указано add? Он знает правила для него, основываясь на файле заголовка, я думаю, но не там, где фактическая реализация есть ....

Там пример, где они разбивают файлы вроде таких, что у них нет что-то вроде #include "add.c" все, что они делают включить файл заголовка в файлы, которые реализуют или используют эту функциональность.

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

+0

Линкер беспокоится о поиске определения. – krsteeve

+0

Вы, как программист, должны сообщить компоновщику, какие объектные файлы и библиотеки должны быть связаны, а также между объектными файлами и библиотеками, вы должны убедиться, что каждая функция или переменная, на которую ссылаются объектные файлы, также где-то определена (другой объект файла или библиотеки). Если у вас нет нескольких исходных файлов, заголовки типа 'sample.h' на самом деле не нужны - в первом примере вы можете сделать' add() 'в статической функции, объявленной в верхней части' main.c', и реализованы на дно. –

ответ

4

Заголовочный файл в C бы объявить функция add для тех модулей, которые нуждаются в ней, но не определить функция. Функция по-прежнему должна быть определена в собственном модуле (, например, в вашем случае, add.c).

Таким образом, в общем, сделать функцию foo доступной для нескольких модулей, вы бы нормально:

  • Выберите файл заголовка (возможно, это самостоятельно, если есть и другие связанные определяет, и т.д.) в заявляютfoo. Например, возможно foo.h бы иметь void foo(...);

  • В некотором модуле, возможно foo.c, вы бы определить полную функцию foo.

  • В любом модуле, который хочет вызвать foo, вы бы #include "foo.h" (или любой другой заголовок вы использовали) и вызвать функцию.

  • При компиляции/связать код, вы убедитесь, что все модули, включая foo.o или любой другой модуль foo, определенные в нем, были присутствуют.

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

+0

Так это просто знает? Если бы я запускал это, это было бы похоже - где также называется этот заголовочный файл, давайте посмотрим там определения ...? – LogicLooking

+0

@LogicLooking Я не уверен, что вы подразумеваете под «это просто знает». Как я указал, вы должны поместить нужные предметы в нужные места. Процесс связывания гарантирует, что символ правильно доступен для всех модулей. Объявление файла заголовка предоставляет вызывающему модулю все необходимое для вызова функции (возврат и типы параметров). – lurker

+0

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

2

Мое понимание заголовков C является то, что они являются «интерфейсы» (например, как Java и других языках), но где вы можете также определить переменную , которые либо установить значения или нет ..

Неправильное использование. Вы не можете «определить» переменные - ну, вы можете, но это приведет к ошибке нескольких определений при компиляции кода, если вы включаете заголовок более одного раза.

Мог ли я сделать это так:

Что касается вашего кода - оба варианта правильны. Язык C использует заголовки для чтения деклараций, и, следовательно, заголовки также являются необязательными. Вы можете разделить свой код на файлы as many as you want .h и .c. Компилятор создаст объектный файл для каждого .c файла. Все файлы .h, включенные в c-файл, в основном встроены в этот файл C «перед компиляцией», то есть на этапе предварительной обработки. Затем компоновщик входит в изображение, которое объединяет объекты для создания исполняемого файла.

Пожалуйста, не стесняйтесь, если что-то неясно в моем ответе.