Функции в языке программирования C. Функции программирования Чистые и Грязные функции


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

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

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

Функция, создаваемая разработчиком, должна иметь определение, а ее применение в программе называют вызовом функции. Например, в JavaScript и РНР (а также в большинстве других языков) такое определение начинается с ключевого слова function , за которым следуют имя функции, пара круглых скобок, внутри которых можно указать список параметров, а затем блок кода, заключенный в фигурные скобки:

Funсtion имя_функции(список_парамeтров) { блок кода }

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

Для вызова функции в том или ином месте программы указывают следующее выражение:

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

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

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

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

Результат работы функции

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

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

Return \возвращаемое значение\;

Приведу пример:

Оклад = 10000; Процент = 15; Выплата = Оклад + Премия(Оклад, Процент); function Премия (Оклад, Процент) { return Оклад * Процент / 100; }

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

Данный программный код написан на вымышленном (абстрактном) языке. Я хотел сказать, что рассмотренный пример иллюстрирует принцип применения функции, а потому не важно, какой именно язык выбрать. Главное, что все изложенное ранее должно позволить вам понять данный код. Тем не менее, признаюсь, что приведенный мной пример написан и на языке JavaScript. Напишите в обычном текстовом редакторе, например, в Блокноте Windows следующие строки:

Оклад = 10000; function Премия(Оклад, Процент) { return Оклад * Процент / 100; } alert("Выплата = " + Выплата);

Это HTML-код с внедренным в него сценарием на JavaScript. Код сценария заключен между тегами и отличается от рассмотренного ранее только встроенной функцией alert () для вывода сообщений в диалоговом окне. Сохраните данный код в файле с расширением htm или html, а затем откройте его в Web-браузере, например, Microsoft Internet Explorer или Mozilla Firefox. В результате появится диалоговое окно с сообщением "Выплата =11500".

Назначение

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

Чтобы такая программа как-то работала без зависаний и выдачи системных сообщений об ошибках, вместо настоящего кода функции можно было временно поставить так называемые заглушки, например, выво­ды специальных сообщений программиста, например, "работает функция mуfunc".

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

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

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

Приведение типов

Возможно, вы заметили одно странное обстоятельство: функции аlert() в качестве параметра передается выражение в виде суммы разнотипных данных (символьного и числового значения):

"Выплата = " + Выплата

Здесь "Выплата =" - символьная строка, а Выплата - переменная числового типа. Ведь ранее упоминалось, что типы данных для того и придуманы, чтобы выполнять операции над однотипными данными. Тем не менее, сообщений об ошибках не было, а результат оказался правильным!

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

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

Методы окружения

Также может вызвать недоумение функция alert() , которая использовалась для вывода на экран диалогового окна с некоторым сообщением. А откуда она взялась? В сценарии же нет ее определения.

Если быть точным, то alert() - не функция языка JavaScript, а метод объекта window , который принадлежит объектной модели браузера. Методами называют внутренние функции объектов. Иначе говоря, этот метод, как и множество других объектов браузера и загруженного в него документа, составляют внешнее окружение сценария на JavaScript. К объектам этого окружения можно обратиться из сценария, т. е. прочитать и даже изменить значения их свойств. Тем самым обеспечивается возможность управлять внешним видом и информационным содержанием Web-страницы.

Разумеется, модель того, с чем требуется иметь дело посредством языка программирования, необходимо знать. Но это особая тема. Сейчас же мы рассматриваем языки программирования, причем с высоты "птичьего полета", и до поры не будем слишком приближаться к "земле".

Страница 51 из 85

1.5.1. Определение и вызов функций

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

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

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

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

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

Int rus (unsigned char r)
{ if (r>="А" && c1 .

Функция, вычисляющая факториал, будет иметь следующий вид:

Long fakt(int n)
{
return ((n==1) ? 1: n*fakt(n-1));
}

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

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

Что такое функция

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

Резюмируем

Итак, функции - это своеобразные контейнеры для группировки алгоритмов. Они:

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

    Предыдущие публикации:

    Так, что же такое "программная функция" ?

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

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

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

    Программная функция - это:

    - "функция осознанных преимуществ",

    - "функция врожденного профессионализма",

    - "функция основных ценностей, основных задач и целей".

    И именно поэтому человеку крайне трудно отступать от своей "программы", не говоря уже о том, чтобы поступать ей наперекор (чего от нас нередко требуют условия психологической несовместимости).

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

    Программная функция определяет предел допустимых уступок.

    - Ну хорошо, - вставляет Читатель, - но если есть в нашей психике "функция целей и задач" , то должна же быть и какая-то функция их достижений?

    Такая функция действительно есть, и с "программной" она тесно сотрудничает, а потому в "Модели "А" находится справа от нее, на 2-й позиции уровня ЭГО (т. е. занимает второй кабинет верхнего этажа). Эта функция называется "творческой" , или "созидательной функцией" .

    Творческая функция и творческий аспект.

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

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

    А теперь вспомним нашу первую классификацию - "сенсорик - этический ","интуит - логический "и т.д. Что мы видим?

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

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

    - А можно это показать на каком-нибудь примере? - интересуется Читатель.

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

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

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

    - Но почему так происходит?

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

    "Элементарная модель" типа ИМ.

    Аспекты, вынесенные на уровень ЭГО ,выражают основные ценности типа .Именно поэтому они вынесены в его название.

    Например, название типа "этико-сенсорный экстраверт" означает, что его "программная" ценность - экстравертная этика ("этика эмоций"), а "творческая" ценность - интровертная сенсорика ("сенсорика ощущений") .

    На уровне ЭГО это выглядит так:

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

    У интроверта, соответственно, наоборот: программная функция будет интровертной (белый символ), а реализационная - экстравертной (черный).

    И еще следует отметить: если программный аспект - рациональный (этика или логика), то он реализуется иррациональным аспектом .

    - Почему?

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

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

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

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

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

    Положительные моменты:

    Функцию в любой момент времени и в любом месте программы можно вызвать на выполнение, причём неоднократно;

    Функции избавляют программиста от рутинного клонирования массы повторяющихся операторов;

    Одну и ту же функцию можно вставить в совершенно разные программы, сокращая тем самым время на разработку и отладку;

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

    Что надо знать о функциях? Во-первых, как правильно их вызывать из программы, во-вторых, как оформлять в отдельные библиотеки, в-третьих, как устанавливать взаимосвязи с другими функциями.

    Функции в языке Си можно условно разделить на три вида: системные, внутренние и внешние.

    Системные функции прилагаются к любому компилятору. В WinAVR их можно найти в библиотечном справочнике, находящемся по адресу C:\WinAVR-2010010\ doc\avr-libc\avr-libc-user-manual.pdf (далее - «Библиотечное руководство»).

    Каждая системная функция входит строго в свою библиотеку. Названия библиотек и функций в разных компиляторах отличаются. Объявление используемых библиотек производится в «шапке» программы директивой препроцессора «#inC1ude ».

    Символ «#» пишется слитно со словом «inC1ude» и обязательно начинается в первом столбце листинга. «Хеддер» - это файл с расширением «.h», в котором описываются параметры функций. К системным также относится головная функция «main», без которой не обходится ни одна программа в языке Си.

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

    Компилятор AVR-GCC, используемый в пакете WinAVR, занимает по сравнению с другими компиляторами золотую середину. В его составе имеются примерно в равной части функции общепринятых стандартов ANSI, C99, а также собственные микроконтроллерные библиотеки.

    Досконально изучив системные функции одного компилятора, программист в какой-то мере «привязывается» к ним и не хочет переучиваться на новые. Вот где требуется поистине шахматный расчёт, чтобы с первого раза выбратьдля изучения солидный, мощный и постоянно обновляемый (а значит, «живой»!) компилятор. К слову сказать, AVR-GCC пока оправдывает все ожидания пользователей.

    В стандартные библиотеки компиляторов, наряду с функциями, входят также системные макроопределения, например, специфические для пакета WinAVR «_BV», «bit_is_set», «bit_is_C1ear». Подробности их применения освещаются в «Библиотечном руководстве».

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

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

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

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

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

    3. Если сделать внешние функции максимально автономными в работе, то их в будущем можно использовать совместно с другими программами. Дальновидные программисты стараются создавать свои «родные» библиотеки, состоящие из специализированных функций. К примеру, хороший набор готовых внешних функций для AVR-контроллеров содержится в бесплатной библиотеке Паскаля Стэнга .

    По устоявшейся традиции, все имена функций, как и имена переменных, записывают малыми латинскими буквами. Цифры допускаются во всех позициях имени, кроме первой слева. Названия системных функций изменять нельзя, они определяются стандартами, в отличие от внутренних и внешних функций, имена которым придумывают, кто как хочет. Единственное ограничение, чтобы новые названия отличались от названий системных функций, иначе компилятор выдаёт сообщение об ошибке: «Error previous definition».

    За именем функции обязательно следуют круглые скобки, в которых при необходимости указывают передаваемые/принимаемые параметры. В Табл. 6.9 перечислены все допустимые форматы объявления и вызова функций в AVR-GCC.

    Таблица 6.9. Форматы объявления и вызова функций в AVR-GCC

    Формат объявления функции __ «example()»