Функции в языке си сообщение

Обновлено: 14.05.2024

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

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

Каждая функция в языке Си должна быть определена, то есть должны быть указаны:

  • тип возвращаемого значения;
  • имя функции;
  • информация о формальных аргументах;
  • тело функции.

Пример: Функция сложения двух вещественных чисел

Различают системные и собственные функции. Системные функции хранятся в стандартных библиотеках, и пользователю не нужно вдаваться в подробности их реализации. Достаточно знать лишь их сигнатуру. Примером системных функций, являются функции printf() и scanf().

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

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

Общий вид вызова функции

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

Пожалуйста, приостановите работу AdBlock на этом сайте.

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

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

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

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

Как устроены функции

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

С телом функции всё ясно: там описывается алгоритм работы функции. Давайте разберёмся с заголовком. Он состоит из трёх обязательных частей:

  • тип возвращаемого значения;
  • имя функции;
  • аргументы функции.

Сначала записывается тип возвращаемого значения, например, int , как в функции main . Если функция не должна возвращать никакое значение в программу, то на этом месте пишется ключевое слово void . Казалось бы, что раз функция ничего не возвращает, то и не нужно ничего писать. Раньше, кстати, в языке Си так и было сделано, но потом для единообразия всё-таки добавили. Сейчас современные компиляторы будут выдавать предупреждения/ошибки, если вы не укажете тип возвращаемого значения.
В некоторых языках программирования функции, которые не возвращают никакого значения, называют процедурами (например, pascal). Более того, для создания функций и процедур предусмотрен различный синтаксис. В языке Си такой дискриминации нет.

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

Давайте посмотрим на заголовки уже знакомых нам функций.

Как создать свою функцию

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

Уточнение структуры программы. Объявление функций.

Рис.1 Уточнение структуры программы. Объявление функций.

Как видите, имеется аж два места, где это можно сделать.

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

Давайте я подробно опишу, как будет работать эта программа. Выполняется тело функции main . Создются целые переменные x , y и m . В переменные x и y считываются данные с клавиатуры. Допустим мы ввели 3 5 , тогда x = 3 , y = 5 . Это вам всё и так должно быть понятно. Теперь следующая строчка

Переменной m надо присвоить то, что находится справа от знака = . Там у нас указано имя функции, которую мы создали сами. Компьютер ищет объявление и описание этой функции. Оно находится выше. Согласно этому объявлению данная функция должна принять два целочисленных значения. В нашем случае это значения, записанные в переменных x и y . Т.е. числа 3 и 5 . Обратите внимание, что в функцию передаются не сами переменные x и y , а только значения (два числа), которые в них хранятся. То, что на самом деле передаётся в функцию при её вызове в программе, называется фактическими параметрами функции.

Теперь начинает выполняться функция max_num . Первым делом для каждого параметра, описанного в заголовке функции, создается отдельная временная переменная. В нашем случае создаются две целочисленных переменных с именами a и b . Этим переменным присваиваются значения фактических параметров. Сами же параметры, описанные в заголовке функции, называются формальными параметрами. Итак, формальным параметрам a и b присваиваются значения фактических параметров 3 и 5 соответственно. Теперь a = 3 , b = 5 . Дальше внутри функции мы можем работать с этими переменными так, как будто они обычные переменные.

Создаётся целочисленная переменная с именем max , ей присваивается значение b . Дальше проверяется условие a > b . Если оно истинно, то значение в переменной max следует заменить на a .

Далее следует оператор return , который возвращает в вызывающую программу (функцию main ) значение, записанное в переменной max , т.е. 5 . После чего переменные a , b и max удаляются из памяти. А мы возвращаемся к строке

Функция max_num вернула значение 5 , значит теперь справа от знака = записано 5 . Это значение записывается в переменную m. Дальше на экран выводится строчка, и программа завершается.

Внимательно прочитайте последние 4 абазаца ещё раз, чтобы до конца уяснить, как работает программа.

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

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

Прототип функции полностью повторяет заголовок функции, после которого стоит ; . Указав прототип в верхнем блоке, в нижнем мы уже можем полностью описать функцию. Для примера выше это могло бы выглядеть так:

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

Практика

Решите предложенные задачи:


Для удобства работы сразу переходите в полноэкранный режим

А теперь нам предстоит разобраться с вопросом о том, как в Си/Си++ реализуется механизм подпрограмм.

Рассмотрим пример. Требуется составить программу нахожде­ния наибольшего значения из трех величин — max (я, Ь, с). Для ее решения можно использовать вспомогательный алгоритм нахож­дения максимального значения из двух, поскольку справедливо равенство: max (а, Ь, с) = max (max (о, b), с).

Вот программа решения этой задачи с использованием вспо­могательной функции.

int MAX(int x, int у )

Формат определения функции следующий:

тип имя_функции (спецификация_параметров)

Тип функции — это тип возвращаемого функцией результата. Если функция не возвращает никакого результата, то для нее ука­зывается тип void.

Имя функции — идентификатор, задаваемый программистом или main для основной функции.

Тело функции — это либо составной оператор, либо блок.

Здесь мы впервые встречаемся с понятием блока. Признаком блока является наличие описаний программных объектов (пере­менных, массивов и т.д.), которые действуют в пределах этого блока. Блок, как и составной оператор, ограничивается фигурны­ми скобками.

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

Оператором возврата из функции в точку ее вызова является опе­ратор return. Он может использоваться в функциях в двух формах:

return; или return выражение;

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

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

Формат обращения к функции (вызова функции) традици­онный:

Между формальными и фактическими параметрами при вызо­ве функции должны соблюдаться правила соответствия по после­довательности и по типам. Фактический параметр — это выраже­ние того же типа, что и у соответствующего ему формального параметра. Стандарт языка Си допускает автоматическое преобра­зование значений фактических параметров к типу формальных параметров, В Си++ такое преобразование не предусмотрено. По­этому в дальнейшем мы будем строго следовать принципу соот­ветствия типов.

Необходимо усвоить еще один важнейший принцип, действую­щий в Си/Си++: передача параметров при вызове функции происхо­дит только по значению. Выполнение функции не может изменить значения переменных, указанных в качестве фактических параметров.

Правило соответствия по количеству в Си в некоторых случаях может не соблюдаться. Более того, в Си возможны функции с переменным числом параметров. Примером таких функций являются библиотечные функции printf () и scanf ().

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

int MAX(int, int); // Основная функция

//Определение функции MAX int MAX(int x, int y) < if (x>y) return x; else return y;

Здесь использован прототип функции. Прототипом называется предварительное описание функции, в котором содержатся все необходимые сведения для правильного обращения к ней: имя и тип функции, типы формальных параметров. В прототипе имена формальных параметров указывать необязательно (как это сдела­но в примере 2), хотя их указание не является ошибочным. Мож­но было написать и так, как в заголовке определения функции;

int MAX(int x, int у);

Точка с запятой в конце прототипа ставится обязательно!

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

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

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

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

А теперь сопоставим программу для вычисления наибольшего общего делителя для суммы, разности и произведения двух чисел на Си++.

int NOD2 (int, int);

Rez=NOD2(NOD2(a+b, abs (a-b)),a*b);

int NOD2(int M, int N)

Рассмотрим программу решения следующей задачи: зная де­картовы координаты вершин выпуклого четырехугольника, вы­числить его площадь.

Математическое решение этой задачи следующее. Обозначим координаты вершин четырехугольника так: (х1,у1), (х2,у2), (х3, у3), (х4, у4). Площадь четырехугольника можно вычислить как сумму площадей двух треугольников. В свою очередь, площадь каж­дого треугольника вычисляется по формуле Герона. Для примене ния формулы Герона нужно найти длины сторон. Длина стороны меж­ду первой и


второй вершинами вы­числяется по формуле:


Аналогично вычисляются дли­ны других отрезков.

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

Функция в C-программировании — это многократно используемый блок кода, который облегчает понимание, тестирование программы и может быть легко изменен без изменения вызывающей программы. Функции делят код и модулируют программу для лучшего и эффективного результата. Короче говоря, большая программа делится на различные подпрограммы, которые называются функциями

Функция в C

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

В этом уроке вы узнаете

Библиотека Vs. Пользовательские функции

  1. Библиотечные функции
  2. Пользовательские функции

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

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

  1. Объявление функции
  2. Определение функции
  3. Вызов функции

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

Объявления функций (называемые прототипом) обычно выполняются над функцией main () и имеют общий вид:

  • Return_data_type : это тип данных значения функции вернулась обратно в вызывающем заявлении.
  • Имя_функции : следуют круглые скобки
  • Имена аргументов с их объявлениями типов данных могут быть заключены в круглые скобки.

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

Имейте в виду, что функция не обязательно возвращает значение. В этом случае используется ключевое слово void.

Например, объявление функции output_message указывает, что функция не возвращает значение: void output_message ();

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

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

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

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

Аргументы функции

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

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

Мы рассмотрим следующую программу, которая демонстрирует параметры, передаваемые по значению:

Читайте также: