Как перемещать функции C в отдельный файл?

Я начинаю с программирования на C. В настоящее время у меня большой файл, содержащий множество функций. Я хотел бы переместить эти функции в отдельный файл, чтобы код был легче читать. Тем не менее, я не могу понять, как правильно включать/компилировать и не могу найти пример в любом онлайн-учебнике, которое я нашел. Здесь упрощенный пример:

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

void func1(void) {
  printf("Function 1!\n");
}

void func2(void) {
  printf("Function 2!\n");
}

int main(void) {
  func1();
  func2();
  return 0;
}

Как вы перемещаете функции C в отдельный файл? FYI: Я использую gcc.

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

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

int counter = 0;

void func1(void) {
  printf("Function 1!\n");
  counter++;
}

int main(void) {
  func1();
  return 0;
}

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

#include <stdlib.h>
#include <stdio.h>
#include "functions.c"

int counter = 0;

int main(void) {
  func1();
  counter = 100;
  return 0;
}

Как я могу обойти эту проблему?

Ответ 1

Хорошо. Вот так.

Ваш файл main.c

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

int main(void) {
  func1();
  func2();
  return 0;
}

Ваш файл functions.h

void func1(void);
void func2(void);

Ваш файл functions.c

#include "functions.h"

void func1(void) {
  printf("Function 1!\n");
}

void func2(void) {
  printf("Function 2!\n");
}

Скомпилируйте это с:

gcc -o main.exe main.c functions.c

Ответ 2

Самый распространенный способ - разместить прототипы функций в файле заголовка и реализации вашей функции в исходном файле. Например:

func1.h

#ifndef MY_FUNC1_H
#define MY_FUNC1_H
#include <stdio.h>

// declares a variable
extern int var1;

// declares a function
void func1(void);
#endif

func1.c

#include "func1.h"

// defines a variable
int var1 = 512;

// defines a function
void func1(void) {
    printf("Function 1!\n");
}

func2.h:

#ifndef MY_FUNC2_H
#define MY_FUNC2_H
#include <stdio.h>
void func2(void);
#endif

func2.c:

#include "func1.h" // included in order to use var1
#include "func2.h"
void func2(void) {
    printf("Function 2 with var1 == %i\n", var1);
}

main.c:

#include <stdio.h>
#include "func1.h"
#include "func2.h"

int main(void) {
    var1 += 512;
    func1();
    func2();
    return 0;
}

Затем вы скомпилируете, используя следующее:

gcc -c -o func1.o func1.c
gcc -c -o func2.o func2.c
gcc -c -o main.o  main.c
gcc -o myprog main.o func1.o func2.o
./myprog

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

Как правило, вы хотите, чтобы заголовочный файл включался один раз, это назначение макросов #ifndef #define #endif в файлах заголовков.

Ответ 3

Сначала вам нужно узнать разницу между декларацией и определением. Объявление сообщает компилятору, что существует что-то вроде функции. Определение - для случая функций - реализация фактической функции.

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

Ответ 4

Вы можете сделать два файла: один с основной функцией, а другой с остальными.

Если ваша функция в другом файле использует глобальную переменную из другого модуля/файла, вам нужно добавить "extern" перед объявлением глобальной переменной в модуле вместе с определением функции. Это говорит компилятору, что вы обращаетесь к глобальной переменной из другого файла.

Ниже приведен пример, в котором определяется глобальная переменная "x" и вызывается функция "myfunction" в файле main.c. "Myfunction" определяется в файле functions.c. "X" также необходимо быть объявленным в файле functions.c, но так как он будет обращаться к "x" из другого файла, перед ним должен быть "extern". "myfunction" принимает внешнюю глобальную переменную "x", увеличивая ее на один и распечатывает его. Рассмотрим следующий код:

main.c будет выглядеть примерно так:

#include <stdio.h>
#include "functions.c"

int x = 1;

int main()
{
    myfunction();
    printf("The value of x in main is: %d\n", x);
    return(0);
}

functions.c будет выглядеть примерно так:

#include <stdio.h>

extern int x;

void myfunction(void)
{
        x++;
    printf("The value of x in myfunction is: %d\n",x);
}

Обратите внимание, что main.c использует "int x;" объявить x, тогда как functions.c использует "extern int x" для объявления x.

Чтобы скомпилировать код, убедитесь, что оба файла находятся в одной папке, и скомпилируйте, как если бы у вас был только один файл. Например, если вы используете gcc в системе linux и gcc, ваш ввод командной строки будет выглядеть так:

gcc main.c -o main
./main

Первая строка компилирует код, а вторая строка запускает его. Вывод должен выглядеть так:

Значение x в myfunction равно: 2 Значение x в main равно: 2

Обратите внимание, что значение "x" также изменяется в основном, так как "x" является глобальной переменной.

Ответ 5

Вы можете сделать что-то вроде этого.

    /* func1.c */
    void func1(void) {
      printf("Function 1!\n");
    }

    /* func2.c */
    void func2(void) {
      printf("Function 2!\n");
    }

    /* main.c */
    #include "func1.c"
    #include "func2.c"

    int main ( void )
    {
    func1();
    func2();
    return 0;
    }