Программирование на Objective-C 2.0
Шрифт:
Табл. В.5. Переменные: сводка классов памяти, областей действия и способов инициализации Класс памяти Место объявления переменной На нее можно ссылаться И инициализировать с помощью Комментарии static Вне любого БЛОКА Внутри данного файла Только константного выражения Переменные инициализируются только один раз при запуске программы; значения сохраняются в пределах БЛОКОВ; значение по умолчанию 0 Внутри какого-либо БЛОКА Внутри этого блока extern Вне любого блока Внутри данного файла Только константных выражения Переменная должна быть определена хотя бы в одном месте без ключевого слова extern или в одном месте с использованием ключевого слова extern с присваиванием начального значения. Внутри какого-либо БЛОКА Внутри этого блока auto Внутри какого-либо
К переменным экземпляра можно получать доступ с помощью любого метода экземпляра, определенного для данного класса в секции interface, где явно объявляется эта переменная, или в категориях, созданных для данного класса. К наследуемым переменным экземпляра тоже можно осуществлять непосред-ственный доступ без каких-либо специальных объявлений. Методы класса не имеют доступа к переменным экземпляра.
Для управления областью действия переменной экземпляра можно исполь-зовать специальные директивы @private, @protected и @риЫк. После появления этих директив они действуют, пока не встретится закрывающая фигурная скобка, заканчивающая объявление соответствующих переменных экземпляра, или пока не будет использована другая из этих трех директив. Например, следующие строки являются началом объявления секции interface для класса с именем Point, содержащего четыре переменные экземпляра. @interface Point: NSObject { @private int internail D; @protected float x; float y; @public BOOL valid; }
Переменная internallD объявлена как private, переменные x и у — как protected (директива по умолчанию), переменная valid — как public.
Эти директивы описываются в таблице В.6.
Табл. В.6. Область действия переменных экземпляра Директива На переменную можно ссылаться Комментарии @protected С помощью методов экземпляра в данном классе, методов экземпляра в подклассах, и методов экземпляра в расширениях категорий на данный класс. Эта директива по умолчанию. @private С помощью методов экземпляра в данном классе, методов экземпляра в расширениях категорий на данный класс, но не из каких-либо подклассов. Эта директива ограничивает доступ самим классом. @public С помощью методов экземпляра в данном классе, методов экземпляра в подклассах и методов экземпляра в расширениях категорий на данный класс; доступ к такой переменной можно также выполнять из других функций или методов, применяя к экземпляру класса оператор косвенного указателя структуры (->), после которого следует имя переменной экземпляра (например, myfract->numerator). Эту директиву следует использовать только при необходимости; она нарушает понятие инкапсуляции данных. Функции
В этом разделе содержатся сведения о синтаксисе и работе функций. Определение функции Общий формат возвращаемыйТип имя (тип1 парам 1, тип2 парам2,..) { Объявления Переменных программныйОператор программныйОператор return выражение; }
Определяется функция имя, которая возвращает значение типа возвращаемый-Тип и имеет формальные параметры парам1, парам2,парам 1 объявляется с типом тип/, парам2с типом тип2, ит.д.
Локальные переменные обычно объяапяются в начале функции, но это не обязательно. Они могут быть объявлены в любом месте, и тогда доступ к ним ограничен операторами, которые следует в функции после их объявления.
Если функция не возвращает значения, то возвращаемыйТип указывается как void.
Если в круглых скобках содержится только void, функция не принимает ни-каких аргументов. Если применяются .. в качестве последнего (или
единственного) параметра в списке, функция принимает переменное число аргументов, например, int printf (char *format, ...) { }В объявлениях для аргументов одномерных массивов не обязательно указывать число элементов этого массива. Для многомерных массивов нужно обязательно указать размер каждой размерности, кроме первой.
Описание оператора return см. ниже в разделе «Оператор return». По-прежнему поддерживается старый способ определения функций. Для этого используется следующий общий формат. возвращаемыйТип имя (парам 1, парам2,„) объявления параметров { ОбъявленияПеременных программныйОператор программныйОператор return выражение, }
Здесь в круглых скобках указываются только имена параметров. Если функция не принимает никаких аргументов, то указываются только левая и правая круглые скобки. Тин каждого параметра объявляется вне круглых скобок и перед левой фигурной скобкой, открывающей определение функции. Например, ниже определяется функция с именем rotate, которая принимает два парамегра с именами value и п. unsigned int rotate (value, n) unsigned int value; int n; { }
Первый аргумент определяется как unsigned int и второй как int.
Перед определением функции можно поместить ключевое слово inline как указание компилятору. Некоторые компиляторы заменяют вызов такой функ-ции конкретным кодом самой функции, что ускоряет выполнение. Ниже пока-зан соответствующий пример. inline int min (int a, int b) { return ( a < b ? a : b); } Вызов функции Общий формат имя ( арг1, арг2,..)
Происходит вызов функции имя, и значения арг1, арг2, ... передаются функ-ции как аргументы. Если функция не принимает никаких аргументов, указы-ваются только открывающая и закрывающая круглые скобки (например, initialize 0).
Если вызывается функция, которая определена после самого вызова или находится в другом файле, то необходимо включить объявление прототипа для этой функции, которое имеет следующий общий формат. возвращаемыйТип имя (тип1 парам 1, тип2 парам2, .. )
Это указывает компилятору тип возвращаемого значения функции, число аргументов, которое она принимает, и тип каждого аргумента. Например, в строке long double power (double x, int n);
содержится объявление power как функции, которая возвращает значение типа long double и принимает два аргумента типа double и типа int. Имена аргументов внутри круглых скобок на самом деле являются фиктивными именами, и они могут быть опущены, то есть long double power {double, int); означает то же самое.
Если компилятор уже встретил определение функции или объявление про-тотипа для этой функции, то при вызове функции тип каждого аргумента пре-образуется (там, где возможно) в соответствии с типом, который объявлен в функции.
Если компилятор не встретил ни определения функции, ни объявления про-тотипа, то он предполагает, что функция возвращает значение типа int, автома-тически преобразует все аргументы типа float в тип double и выполняет целочисленное расширение любых целых аргументов, как описано выше в разделе «Преобразование базовых типов данных». Другие аргументы функции передаются без преобразования.
Функции, которые принимают переменное число аргументов, должны быть объявлены соответствующим образом. В противном случае компилятор будет предполагать, что функция принимает фиксированное число аргументов, ос-новываясь на числе аргументов, фактически использованных при вызове фун-кции.
Если функция была определена в старом формате (см. выше раздел «Определение функции»), то объявление для такой функции имеет следующий формат. возвращаемыйТип имя ;
Аргументы, передаваемые такой функции, преобразуются в соответствии с описанием в предыдущем абзаце.
Для функций, возвращаемый тип которых объявлен как void, компилятор выводит сообщение для любых вызовов, где делается попытка использования возвращаемого значения.
Все аргументы передаются функции по их значению, поэтому их значения не могут быть изменены функцией. Но если функции передается указатель, то функция может изменить значения, которые указываются этим указателем, но она все же не может изменить значение самой переменной-указателя. Указатели на функции
Имя функции без последующей пары круглых скобок создает указатель на эту функцию. К имени функции можно также применить адресный оператор, что-бы создать указатель на эту функцию.