Функции, объявленные и определенные в файле .c - PullRequest
0 голосов
/ 30 мая 2018

Когда я просматривал огромный исходный код, я натолкнулся на несколько файлов, в которых есть только одна функция, объявленная, скажем, в «code.h», но в «code.c» есть много объявленных и определенных функций.

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

Было бы полезно, если кто-нибудь может привести пример.Спасибо

Ответы [ 4 ]

0 голосов
/ 30 мая 2018

Я бы посоветовал прочесть ключевое слово "extern".

Из того, что я понимаю в вашем вопросе, у вас есть два файла - "code.h" и "code.c".Однако «code.h» объявляет только некоторые функции в «code.c»:

code.h

int func1();
int func2();

code.c

int func1()
{
  return 1;
}

int func2()
{ 
  return 2;
}

int func3()
{ 
  return 3;
}

main.c

#include "stdio.h"
#include "code.h"

extern int func3();

int main()
{
  printf("%d ", func1());
  printf("%d ", func2());
  printf("%d ", func3());
}

Компиляция с использованием gcc:

gcc main.c code.c

выход:

main.c: In function ‘main’:
main.c:10:17: warning: implicit declaration of function ‘func3’ [-Wimplicit-function-declaration]
   printf("%d ", func3());

и при выполнении:

1 2 3

Ключевое слово "extern" в основном говорит компилятору "есть определение для функции с этим объявлением" для компиляции.Во время ссылки компоновщик найдет определение и ссылку на него.

Это, однако, неуклюжий способ сделать это, так как вызывающий ("main.c") должен знать, что происходит в "коде"..c ", и постоянно добавляйте больше внешних объявлений и т. д. и т. д.

Так что лучше включите функции, которые вы хотите иметь глобальную область видимости, в" code.h ".Если в «code.c» есть функции, которые не имеют глобальной области видимости, рассмотрите возможность сделать их «статическими».

Еще немного прочтения: Влияние ключевого слова extern на функции C

0 голосов
/ 30 мая 2018

Как мы можем получить доступ к одной из этих функций в исходном файле из другого исходного файла?

В этом и заключается идея определения некоторых функций в заголовке, а некоторых только вc-файл.

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

0 голосов
/ 30 мая 2018

Причина, по которой это делается, состоит в том, чтобы разбить код на более чистый и отсортированный формат, чтобы функции, относящиеся к конкретной операции, можно было объединить в один файл и затем вызвать из другого файла.ПРИМЕЧАНИЕ: это не обязательно делать, но это хорошая практика программирования.

Теперь есть два способа сделать это: 1. включая файлы 2. объявить функцию как внешнюю и затем связать их во время связывания.

1.Включение файла - это метод, который вы, вероятно, видите в своем коде под рукой.Функции определены в одном файле, и этот файл включается с помощью #include «filename. [H / c]», а затем вызывая функцию, как было объявлено в данном файле.

file_to_include.c

void my_func()
{
printf("Hello!\n");
}

file_that_include.c

#include<stdio.h>
#include"file_to_include.c"
int main()
{
 my_func();
 return 0;
 }

для компиляции вы просто выполните

gcc file_that_include.c
используя extern, вы можете сделать то же самое, но без использования директивы #include

file_to_include.c

void my_func()
{
printf("Hello!\n");
}

file_that_include.c

#include<stdio.h>

extern void my_func();
int main()
{
 my_func();
 return 0;
 }

В этом случае при компиляции вам нужно предоставить оба файла компилятору

gcc file_that_include.c file_to_include.c
0 голосов
/ 30 мая 2018

Разделение сложной подпрограммы на несколько более мелких подпрограмм может облегчить понимание кода, а также позволит вам следовать принципу единой ответственности ( Что является примером принципа единой ответственности? ).Объявляя и определяя их только в файле .c (и объявляя их static), вы можете скрыть внутренние детали от пользователей.

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

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

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

--- edit--

Как мы можем получить доступ к одной из этих функций в исходном файле из другого исходного файла?

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

Пример:

ac

int secret_a(int x)
{
    return x+1;
}

main.c

#include <stdio.h>

//access a secret function from a.c
int secret_a(int);

int main()
{
    printf("secret_a(3) gives: %d\n", secret_a(3));
    return 0;
}
  • (*) везде, где это разрешено языком C
...