C Урок 12. Функции



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

С функциями мы уже ранее имели дело, да, причём, постоянно ими пользуемся. Например, мы практически в каждом уроке используем для вывода в консоль функцию printf, а также для ввода данных от пользователя — функцию scanf. Причём используем мы их по нескольку раз в нашем коде. Также мы постоянно используем в коде функцию main(), представляющую собой точку входа в программу. А представьте себе, что мы выводили бы в консоль с помощью написанного нами алгоритма и постоянно в коде функции main() писали бы этот алгоритм при надобности его использования. Код был бы очень огромен и ни о какой его читабельности не было бы и речи.

Что же такое функция и как она используется?

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

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

Вот так вот выглядит функция

 

 

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

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

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

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

 

 

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

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

Классический вызов функции выглядит примерно так:

 

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

Давайте к нему и приступим.

Проект сделаем из проекта MYPROG11 прошлого занятия и имя ему было присвоено MYPROG12.

Откроем файл main.c и в функции main(), как обычно, удалим весь код тела кроме возврата нуля, останется от него вот это

 

int main()

{

   return 0; //Return an integer from a function

}

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

Наша функция не будет ничего ни принимать, ни возвращать. И расположим мы её выше функции main().

 

 

Функция будет просто выводить какой-то определённый текст в консоль

 

 

Теперь давайте нашу функцию вызовем в функции main()

 

 

Соберём и запустим наш код

 

 

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

 

 

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

 

 

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

 

 

Попробуем собрать наш код. Код соберётся, причём будет работать, но мы получим кучу предупреждений

 

 

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

 

 

Попробуем теперь собрать и запустить нашу программу

 

 

Вот теперь всё отлично!

Ещё ниже последней функции добавим теперь функцию, которая будет уже возвращать результат

 

 

Также добавим на неё прототип

 

 

В функции main() добавим две локальные переменные, сразу их проиициализируем

 

 

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

 

 

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

Классически надо было бы сначала объявить переменную

 

int x;

 

потом вызвать функцию и присвоить её результат объявленной переменной

x = Sum (a, b);

 

а уж потом этот результат использовать в функции prinf

 

printf ("%d + %d = %d\r\n", a, b, x);

 

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

Соберём код и запустим нашу программу

 

 

Всё работает!

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

Всем спасибо за внимание!

 

 

Предыдущий урок Программирование на C Следующий урок

 

Исходный код

 

 

Смотреть ВИДЕОУРОК (нажмите на картинку)

 

C Функции

3 комментария на “C Урок 12. Функции
  1. Андрей:

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

    • Спасибо!
      Не все это понимает. Кто-то (а таких очень много) хочет, чтобы я при этом ещё пел и плясал. Ну, видимо, это не наши люди, они ищут причины того, что не могут научиться ничему. А на самом деле, просто не хотят.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

*