ПРОГРАММИРОВАНИЕ ПОД IPHONE, IPAD OBJECTIVE-C Часть 1

Функции

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

Если бы программа состояла из длинной, непрерывной последовательности утверждений, то было бы трудно найти и исправить ошибки. Кроме этого, мы были бы вынуждены дублировать код в этой программе, а это усложняло бы поиск и исправление тех самых ошибок. Нам бы пришлось исправлять код не в одном месте, а во всех, где используется дублированный код. Для решения этой проблемы были придуманы функции. Например, вы можете написать функцию для вычисления длинны отрезка. Затем, убедившись, что эта часть код работает вы можете его использовать в любой части программы. Вам никогда не прийдется проверять, есть ли в нем ошибки. Это понятие использования функций настолько глобально, что всегда есть по крайней мере одна функция в программе: main(). Благодаря ей компилятор знает, где должно начаться выполнение кода после запуска. Давайте взглянем на функцию main() подробнее:

<code data-result="[object Object]">main ()
{
    //Тело функции main(). Добавьте свой код сюда.
}</code>

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

<code data-result="[object Object]">main ()
{
    //Ниже объявляются переменные
    float pictureWidth, pictureHeight, pictureSurfaceArea;
    //Мы инициализируем переменные (присваиваем им значения)
    pictureWidth = 8.0f;
    pictureHeight = 4.5f;
    pictureSurfaceArea = pictureWidth * pictureHeight;
}</code>

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

<code data-result="[object Object]">main ()
{
    float pictureWidth, pictureHeight, pictureSurfaceArea;
    pictureWidth = 8.0f;
    pictureHeight = 4.5f;
    pictureSurfaceArea = pictureWidth * pictureHeight;
}

circleArea()
{

}</code>

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

<code data-result="[object Object]">main ()
{
    float pictureWidth, pictureHeight, pictureSurfaceArea,
    circleRadius, circleSurfaceArea;
    pictureWidth = 8.0f;
    pictureHeight = 4.5f;
    circleRadius = 5.0f;
    pictureSurfaceArea = pictureWidth * pictureHeight;
    //Здесь мы вызываем наше функцию
    circleSurfaceArea = circleArea(circleRadius);
}

circleArea(float theRadius)
{
    float theArea;
    theArea = 3.14159f * theRadius * theRadius;
    return theArea;
}</code>

Мы добавили переменные circleRadius и circleSurfaceArea, а также инициализировали переменную circleRadius. Наиболее интересной является строка, в которой мы вызываем функцию circleArea(). Вы можете видеть, что название переменной circleRadiusбыло помещено между круглыми скобками. Это аргумент функции circleArea(). Значение переменной circleRadius будет передано функции circleArea(). Когда функция circleArea() закончит вычисления, она должна вернуть результат. Для того чтобы это работало мы изменили саму функцию circleArea(). То, что находиться между скобками после имени функции называется аргументом. После получения этот аргумент храниться в переменной theRadius. Для хранения результата расчета мы используем вторую переменнуюtheArea, поэтому мы должны объявить ее. Cледует заметить, что объявление переменной theRadius делается в скобках. Последняя строка тела функции circleArea() возвращает результат в функцию main(), в то место откуда она была вызвана. В результате переменной circleSurfaceArea установлено это значение. Для завершения нам следует указать тип результата, который возвращается функцией.

<code data-result="[object Object]">float circleArea(float theRadius)
{
    float theArea;
    theArea = 3.14159f * theRadius * theRadius;
    return theArea;
}</code>

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

<code data-result="[object Object]">int throwDice()
{
    int noOfEyes;
    //Код для генерации случайного значения
    return noOfEyes;
}</code>

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

<code data-result="[object Object]">void beepXTimes(int x)
{
    //Код для мычания Х раз;
}</code>

Если функция принимает более одного аргумента как, например, функция pictureSurfaceArea() ниже, эти аргументы разделяются запятыми.

<code data-result="[object Object]">float pictureSurfaceArea(float theWidth, float theHeight)
{
    //Код для расчета площади поверхности
}</code>

Функция main(), в соответствии с соглашением, должна возвратить целое число, так и есть — у нее тоже есть оператор return. Он должен возвратить 0, чтобы показать, что функция выполнилась без проблем. Т.к. функция main() возвращает целое число, мы должны написать int перед main(). Теперь давайте напишем весь код, который мы имеем в одном списке.

<code data-result="[object Object]">float circleArea(float theRadius); //Объявление функции
int main ()
{
    float pictureWidth, pictureHeight, pictureSurfaceArea,
    circleRadius, circleSurfaceArea;
    pictureWidth = 8.0f;
    pictureHeight = 4.5f;
    circleRadius = 5.0f;
    pictureSurfaceArea = pictureWidth * pictureHeight;
    circleSurfaceArea = circleArea(circleRadius);
    return 0;
}

float circleArea(float theRadius)
{
    return (3.14159f * theRadius * theRadius);
}</code>

Как вы заметили наш код начинается с объявления функции circleArea(). Без этого объявления компилятор не будет знать о существовании функции circleArea(). Кроме этого, я изменил само тело функции circleArea(), переменная theArea была нужно только как пример локального определения переменной в функции. На самом деле, можно совмещать вычисление и возврат результата в одном операторе. Код внутри функции защищен от воздействия извне (от основной программы и кода других функций). Что это означает, что значение переменной внутри функции по умолчанию не влияет на любую другую переменную в любой другой функции, даже если он имеет такое же название. Это является наиболее важной чертой Objective-C. Хотя функции, которые мы создали в этой главе, достаточно тривиальные, важно понимать главное — теперь вы можете свободно изменять тело функции не влияя на остальной код, который эту функцию вызывает. Конечно, это все верно только пока вы не измените заголовок функции (т.е. ее имя, список параметров и возвращаемое значение, указанные в первой строчке).

Comments are closed.