Вызов функции из основной программы

Содержание

Я изучаю C, но у меня большой опыт работы с языками программирования более высокого уровня, такими как Java.

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

у нас есть два файла

main.c add.c

main.c вызывает функцию add(int x,int y) С добавить добавить.c, но я ошибочно скомпилировал перед #включая add.c и это сработало ! Что делает его более запутанным, так это то, что когда я #include add.c, он дает ошибку множественного определения на функции add

автор: MohamedEzz

4 ответов

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

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

Уроки Arduino #13 — создаём свою функцию


int square(int i)

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

int square(int i);

и компилятор ожидал бы, что функция «квадрат» определена в другом месте.

теперь, если у вас есть два разных файла, которые вы хотите взаимодействовать (например, предположим, что функция «квадрат» определена в add.c, и вы хотите вызвать квадрат (10) в main.c), вам нужно сделать и определение и объявление. Во-первых, вы определяете квадрат вдобавок.c. Тогда ты!—25—>объявить это в начале main.c. Это позволяет компилятору знать, когда он компилирует main.c что существует функция «квадрат», которая определена в другом месте. Теперь вам нужно скомпилировать оба main.c и add.C в объектные файлы. Вы можете сделать это, позвонив

gcc -c main.c gcc -c add.c

это приведет к созданию файлов main.O и добавить.o. Они содержат скомпилированные функции,но не являются полностью исполняемыми. Важно понять, что здесь главное.o «неполный» в некотором смысле. При компиляции основной.o, вы сказали ему, что функция «квадрат» существует, но функция «квадрат» не определена внутри main.o.

Таким образом, главный.o имеет своего рода» висячую ссылку «на функцию»квадрат». Он не будет компилироваться в полную программу, если вы не объедините ее с другой .o (или a .так или иначе .а) файл, который содержит определение «квадрат». Если вы просто попытаетесь ссылке main.о в программу, т. е.

gcc -o executable main.o

вы получите ошибку, потому что компилятор попытается resolve болтающаяся ссылка на функцию «квадрат», но не найдет для нее никакого определения. Однако, если вы включаете add.o при связывании (связывание-это процесс разрешение все эти ссылки на неопределенные функции при преобразовании .o файлы в исполняемые файлы или .so files), то не будет никаких проблем. т. е.

Python для начинающих. Что такое вызов функции. #3


gcc -o executable main.o add.o

вот как функциональные использовать функции в файлах C, но стилистически, то, что я только что показал вам, — это «неправильный путь». Единственная причина, по которой я сделал это, потому что я думаю, что это лучше поможет вам понять, что происходит, а не полагаться на «#include magic».

Теперь вы, возможно, заметили, что все становится немного грязным, если вам нужно переопределить каждую функцию, которую вы хотите использовать в верхней части main.c вот почему часто программы C используют вспомогательные файлы, называемые «заголовками», которые имеют a .продление сек. Идея заголовка заключается в том, что он содержит просто объявления функций,без их определения. Таким образом, для компиляции программы используются функции, определенные в add.c, вам не нужно вручную объявлять каждую функцию, которую вы используете, и вам не нужно #включать все добавление.C файл в коде. Вместо этого вы можете #include add.H, который просто содержит декларации всех функций add.c.

Читайте также:
Лучшая программа для битов на компьютер

теперь, обновление на #include: #include просто копирует содержимое одного файла в другой. Так, например, код

abc #include «wtf.txt» def

в точности эквивалентно

abc hello world def

предполагая, что wtf.txt содержит текст «hello world».

Итак, если мы поместим все объявления add.c in add.h (т. е.

int square(int i);

, а затем в верхней части Главного.c, пишем

#include «add.h»

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

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

однако заголовки также имеют еще одно общее использование. Предположим, что главное.c использует функции из 50 различных файлов. Верхняя часть main.C будет выглядеть так:

#include «add.h» #include «divide.h» #include «multiply.h» #include «eat-pie.h» .

вместо этого люди часто перемещают все эти #includes в main.H файл заголовка и просто #include main.h от main.С. В этом case, файл заголовка служит два целей. Он объявляет функции в main.c для использования при включении в другие файлы,и он включает в себя все зависимости main.c при включении из main.c.

Использование его таким образом также позволяет цепи зависимостей. Если вы #include add.h, вы не только получаете функции, определенные в add.c, но вы также неявно получаете любые функции, которые добавляют.c использует и любые функции они использовать, и так на.

кроме того, более тонко, #включая файл заголовка из собственного.C файл неявно проверяет наличие ошибок, которые вы делаете. Если, например, вы случайно определили квадрат как

double square(int i);

in add.h, вы обычно не могли бы понять, пока вы не связываете это основное.o ищет один определение квадрата и добавление.o обеспечивает другое, несовместимое один. Это приведет к тому, что вы получите ошибки при связывании, поэтому вы не поймете ошибку пока позже в процессе сборки. Однако, если вы #include add.h от add.c, для компилятора ваш файл выглядит как

#include «add.h» int square(int i)

который после обработки оператора #include будет выглядеть как

double square(int i); int square(int i)

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

почему вы может использовать функцию, не объявляя ее

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

еще одна распространенная практика-использование «защитников заголовка». Чтобы объяснить это, давайте рассмотрим возможную проблему. Допустим, у нас есть два файла: herp.c и derp.C, и они и хотите используйте функции, содержащиеся друг в друге. Следуя приведенным выше рекомендациям, у вас может быть герпес.h с линией

#include «derp.h»

и баттхерт.h с линией

#include «herp.h»

теперь, если вы думаете об этом, #включить «derp.h » будет преобразован в содержимое derp.h, который в свою очередь содержит строку #include «herp.h», который будет преобразован в содержимое herp.h, и это содержит. и так далее, поэтому компилятор будет продолжать вечно просто расширять включает. Аналогично, если main.h #включает в себя оба герпеса.h и derp.h, и оба герпеса.h и derp.ч добавить.h, мы видим это в основном.h, мы заканчиваем с два копии add.h, один в результате #включая herp.h, и один в результате включения derp.h. Итак, решение? «Защита заголовка», т. е. фрагмент кода, который предотвращает включение любого заголовка #дважды. Для добавления.h, например, обычный способ сделать это:

#ifndef ADD_H #define ADD_H int sqrt(int i); . #endif

этот кусок кода по сути указание препроцессору (части компилятора, которая обрабатывает все операторы «#XXX») проверить, определен ли» ADD_H».

Если это не так (еслиndef) затем он сначала определяет » ADD_H «(в этом контексте ADD_H не должен быть определен as ничего, это просто логическое значение, которое либо определено, либо нет), а затем определяет остальную часть содержимого заголовка. Однако, если ADD_H уже определен, то #включая этот файл будет делать ничего, потому что нет ничего за пределами #ifndef блок.

Таким образом, идея заключается в том, что только в первый раз, когда он включен в любой данный файл, он фактически добавит любой текст в этот файл. После этого #including не добавит никакого дополнительного текста в ваш файл. ADD_H-это просто произвольный символ, который вы выбираете для отслеживания добавления.h еще не включен.

Для каждого заголовка вы используете другой символ, чтобы отслеживать, включен он или нет. Например, герпес.ч вероятно, использовать HERP_H вместо ADD_H. Использование «header guard» исправит любую из проблем, перечисленных выше, где у вас есть дубликаты включенных копий файла или бесконечный цикл #includes.

Читайте также:
В какой программе лучше делать хромакей

автор: Jeremy Salwen

проблема в том, что вы не должны быть #include ing a .файл c.

чтобы использовать функцию в другом файле, вам нужно ее объявить. Обычно, каждый .C файл (кроме main.c)имеет связанный заголовок (.h) файл, который правильно объявляет все функции, определенные в .файл c. Ты можешь!—11—>объявить столько раз, сколько вы хотите (пока все объявления идентичны), но может быть только один определение.

что происходит, когда вы #include «add.c» это текст добавить.c входит в состав main.c, давая main.с определение (и, как побочный эффект, в объявлении) add . Затем при компиляции add.c самостоятельно, что создает другое определение add . Таким образом, есть два определения функции, и компилятор волнуется, потому что он не знает, какой из них использовать.

если вы измените его на #include «add.h» , где добавить.ч выглядит примерно так:

#ifndef ADD_H #define ADD_H extern int add(int x, int y); #endif /* ADD_H — Google «include guard» for more info about this trickery */

затем main.c имеет заявление add и может использовать функцию, но определение of add довольно твердо только в add.C файл, и поэтому он существует только один раз, и поэтому он будет компилироваться правильно.

автор: Chris Lutz

вот простой пример вызова функции из другой программы C

позвольте мне назвать основную программу как основную.c и программа, которая содержит функцию как функцию.c для функции.c я создаю файл заголовка, называемый function.h

#include»function.h» int main()
int function(int a,int b)
int function(int,int);

Для компиляции используйте приведенную ниже команду

G++ main.функция c.c-o главный

Вот подробное объяснение. В основной программе я вызвал функцию для суммирования 2 чисел. Значения 1 и 2 в основной программе были поданы в функцию в функции.c через функцию заголовка.h, который содержит точку доступа или мост к функции.с

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

добавить инструкцию печати, чтобы проверить результат или использовать echo $? после выполнения файла main

автор: Shameerariff

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

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

если вы включаете определения функций, они будут экспортированы, если вы не укажете их хранение с помощью static . Поскольку вы также компилируете и связываете add.c , вы не можете добавить это с тех пор ни один или оба ваших объектных файла затем будут экспортировать add .

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

Источник: askdev.ru

Пользовательская функция в C

bestprogrammer.ru

Системный вызов Waitpid на C

Программирование и разработка

На чтение 4 мин Просмотров 224 Опубликовано 21.09.2022

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

Преимущества использования функций в программе:

  • Избежать дублирования кода в программах можно с помощью функций. Код можно писать быстрее, и в результате он становится более читабельным.
  • Код можно разделить и покорить с помощью функций. Этот процесс известен как «Разделяй и властвуй». Трудно писать большие объемы кода внутри основной функции, а также
  • Проводить тестирование и отладку. Наша одна задача может быть разделена на несколько более мелких подзадач с помощью функций, что снижает общую сложность.
  • Например, при использовании pow, sqrt и т. д. в C, не зная, как это реализовано, можно скрыть детали реализации с помощью функций.
  • Практически без модификаций функции, разработанные в одной программе, можно использовать в другой, что сокращает время разработки.

Элементы пользовательской функции в C

Прототип функции

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

Синтаксис:

return_type function_name(type1 arg1, type2 arg2, … typeN argN);

Объявление функции

Здесь return_type функции — это целое число, а имя функции — sum(), которое имеет два аргумента типа int, переданные функции.

Определение функции

После вызова функции определение функции содержит фактический блок кода, который будет выполнен. Четыре компонента определения функции следующие:

  • Тип возвращаемого значения функции
  • Имя функции
  • Параметры функции
  • Тело функции

Вызов функции

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

Синтаксис:

function_name(arg1, arg2, . argN);

Пример:

Читайте также:
Программа nvidia share не работает

add(10,14);

Вызов по значению

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

Пример:

Источник: bestprogrammer.ru

Программирование на языке Python (§ 54 - § 61)

2. Подпрограммы на языке Паскаль

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

3. Нарисовать елку с помощью *

4. Оформление

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

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

• Тексты процедур и функций
записываются в конце раздела
описаний основной программы (перед
служебным словом begin).

6. ПРОЦЕДУРЫ

Формат:
Procedure (формальные
параметры: тип);
;
begin

end;

7. Пример 1

procedure Min (i, j : integer; x, y: real);
– Заданы только вводимые параметры
(аргументы): i, j – целые,
– x, y – вещественные величины.

8. Пример 2

procedure Max (i, j: integer; var u: real);
– вводимые параметры (аргументы):
• i, j – целые числа,
– выводимые параметры (результат):
• u – вещественное число.
– Выводимые параметры (результаты)
записываются с использованием
служебного слова var.
– Если выводимые параметры разных типов,
то слово var записывается перед каждым
типом данных.

9. Пример 3

procedure Min (i: integer; x: real; var j:
integer; var u, v: real);
В тексте процедуры описывать
величины, которые введены в
заголовке, ещё раз не надо.

10. Вызов процедуры

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

11. Пример вызова процедуры

procedure Min (i, j : integer; x, y: real);
Min (k, 10, z, 2.35);
i получает значение величины k
основной программы,
j значение 10,
x значение z,
y значение 2,35.
procedure Max (i, j: integer; var u: real);
Max (l, 35, x);

12. Главное при записи оператора вызова процедуры

это совпадение типов величин и значений,
которые записаны в операторе вызова с типами,
которые определены в заголовке процедуры.
– Формальные параметры – это величины, которые
введены в заголовке процедуры, в скобках.
– Фактические параметры – это величины, которые
используются в основной программе.
– Между фактическими и формальными
параметрами должно существовать соответствие:
• По количеству параметров;
• Порядку их следования;
• Типу данных.

13. Глобальные и локальные переменные

• Глобальные переменные
описываются в основной программе и
действуют как в основной программе,
так и во всех ее подпрограммах.
• Локальные переменные описываются
в процедуре и действуют только в
пределах этой подпрограммы.

14. Задача: Задача: Дан 2-х мерный массив целых чисел А(m x n), где m

Задача: Задача: Дан 2-х мерный массив целых чисел А(m x n), где
m строках отрицательные элементы заменить 0. Вывести изменённый
массив. Ввод, вывод и изменение оформить в виде процедур.
Program Proc;
procedure out ;
begin
отрицательные заменить на 0>
for i:= 1 to l do
var A: array [1..10, 1..10] of integer;
begin
l,k,i,j: integer;
for j:= 1 to
procedure vvod ;
writeln;
begin
end;
for i:= 1 to l do
end;
for j:= 1 to k do read (A[i,j ]);
writeln
end;
procedure zam;
Begin
begin
readln (l,k);
for i:= 1 to l do
vvod ;
for j:= 1 to k do
zam;
if i mod 2 = 0 then
out ;
if A [i,j] < 0 then A [i, j] := 0
End.
end;
k do write (A[i, j], ‘ ‘);

15. ФУНКЦИИ

Формат:
function (список
формальных параметров):тип
результата функции;
В качестве выводимого параметра
используется имя функции.

16. Пример описания функции

Нахождение максимального из двух
целых чисел
Function max(a,b:integer):integer;
begin
if a>b then max:=a
else max:=b;
end;

17. Вызов функции Function max(a,b:integer):integer;

• В основной программе имя функции
используется в выражениях как
величина.
• После имени функции в скобках
вместо формальных параметров
через запятую записываются
фактические величины или значения.
z:=0.5+max(4,y);

18. Пример: Найти площадь 4-х угольника, используя формулу Герона. Вычисление площади треугольника оформить в виде функции.

Program func;
используя формулу Герона.>
Var a, b, c, d, e, s: real;
Function pl_tr(x1, x2, x3:real): real;
Var p: real;
begin
P:=(x1+x2+x3)/2;
pl_tr:=sqrt(p*(p-x1)*(p-x2)*(px3));
end;
Begin
writeln(‘Введите стороны четырехугольника’);
Readln(a, b, c, d, e);
S:=pl_tr(a, b, c)+pl_tr(c, d, e);
writeln(‘S=’, s:4:2);
End.

19. Задания(использовать процедуры и функции)

1. Дан двумерный массив. Положительные
элементы заменить на 2, а
отрицательные – на -2.
2. Ввести два целых числа. Найти их сумму,
разность, частное и произведение.
3. Треугольник задан координатами своих
вершин. Найти периметр треугольника.
Вычисление длины отрезка оформить в
виде подпрограммы.

Источник: ppt-online.org

Рейтинг
( Пока оценок нет )
Загрузка ...
EFT-Soft.ru