Чтение онлайн

на главную - закладки

Жанры

Программирование на Objective-C 2.0
Шрифт:

Последний оператор if намного понятнее, чем предыдущий. Конечно, данное определение позволяет проверить на високосный год только переменную year, но мы можем написать определение, с помощью которого можно проверить на високосный год любое выражение. Для этого нужно включить в определение один или несколько аргументов.

IS_LEAP_YEAR можно определить с аргументом у следующим образом. #define IS_LEAP_YEAR(y) у % 4 == 0 && у % 100 != 0 \ || у % 400 == 0

В отличие от определения метода, мы не определяем тип аргумента у, поскольку здесь выполняется

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

Используя это определение, напишем оператор if ( IS_LEAP_YEAR (year))

Оператор проверяет, является ли значение для year високосным годом. Можно написать аналогичное выражение для nextYear. if ( IS_LEAP YEAR (nextYear))

В этом операторе определение для IS_LEAP_YEAR непосредственно подставляется в оператор if с заменой аргумента у на nextYear. В результате компилятор будет обрабатывать следующий оператор. if ( nextYear % 4 == 0 && nextYear % 100 != О |j nextYear % 400 == 0)

Определения часто с одним или несколькими аргументами то называют макросами. В следующем макросе представлен квадрат его аргумента. #define SQUARE(x) х * х

В определении для SQUARE необходимо учитывать возможность следующей ошибки. Исходя из нашего описания, оператор у = SQUARE (v);

присваивает у значение V2. Но в операторе у = SQUARE (v+1);

переменной не присваивается значение (v + 1)2, как ожидалось. Поскольку в определении этого макроса препроцессор выполняет подстановку текста вместо аргумента, здесь получится следующее выражение: у = v + 1 * v + 1;

Чтобы решить проблему, нужно использовать в определении макроса SQUARE круглые скобки. #define SQUARE(x) ( (х) * (х))

Определение может показаться несколько странным, но помните, что х будет заменяться подставляемым выражением. Теперь оператор у = SQUARE (v+ 1);

будет правильно обработан как У = ((v+ 1) * (v+ 1)); Следующий макрос позволяет создавать новые дроби из нашего класса Fraction. #define MakeFract(x.y) ([[Fraction alloc] initWith: x over: y]])

Теперь для сложения дробей nl/dl и n2/d2 можно писать такие выражения, как myFract = MakeFract (1, 3); // Создание дроби 1/3

или sum = [MakeFract (nl, d1) add: MakeFract (n2, d2)];

Макросы удобны для работы с условными выражениями. В следующей строке определяется макрос с именем МАХ, определяющий максимальное из двух значений. #define MAX(a,b) { ((а) > (Ь)) ? (а): (Ь))

С помощью этого макроса можно писать такие операторы, как limit = МАХ (х + у, minValue);

Переменной limit присваивается максимальное из двух значений: х + у и minValue. Все определение МАХ заключено в круглые скобки, чтобы правильно обрабатывать такие выражения, как МАХ (х, у)* 100

Каждый аргумент тоже заключен в круглые скобки, чтобы правильно обрабатывать такие выражения, как МАХ (х &

у, z)

Оператор & — это побитовый оператор AND, и он имеет меньший приоритет, чем оператор > в данном макросе. Без этих круглых скобок оператор > обрабатывался бы раньше побитового AND, что давало бы неверный результат.

В следующем макросе проверяется, является ли символ строчной буквой. #define IS_LOWER_CASE(x) ( ((х) >= 'а') && <(х) <= ’z') )

С помощью этого макроса можно писать такие выражения, как if ( IS_LOWER_CASE (с))

Этот макрос можно даже использовать в определении другого макроса, чтобы преобразовывать символ из нижнего регистра в верхний (делать строчную букву прописной), не изменяя другие символы. #define T0_UPPER(x) ( IS_LOWER_CASE (х) ? (х) -'a' + 'A' : (х))

Здесь мы снова работаем со стандартным набором символов ASCII. В части II, когда будут описываться объекты-строки, вы увидите, как выполнять преобразование символов из одного регистра в другой для международных наборов символов (Unicode). Оператор

Если поместить символ # перед параметром в определении макроса, препроцессор создаст строку-константу в стиле С из аргумента макроса при его вызове. Например, определение #define str(x) # х

при последующем вызове str (testing)

будет раскрыто препроцессором как "testing"

Например, вызов printf printf (str ("Программировать на Objective-C интересно""));

эквивалентен printf ("Программировать на Objective-C интересно");

Препроцессор заключает в кавычки фактический аргумент макроса. Препроцессор сохраняет в аргументе все кавычки и обратные слэши. Поэтому вызов str ("hello")

даст в результате "\"hello\"" Более близкий к практике пример оператора # представляет следующее определение макроса. define printint(var) printf (# var " = %i\n", var) Этот макрос используется для вывода значен ия целой переменной. Если count — переменная целого типа со значением 100, то оператор

printint (count); будет раскрыт как

printf ("count" " = %i\n", count); Компилятор выполнит конкатенацию двух смежных литеральных строк, чтобы создать одну строку. Поэтому после конкатенации оператор примет следующий вид.

printf ("count = %i\n", count); ### Оператор ## В определении макроса оператор ## сливает два маркера. Он ставится перед именем параметра макроса (или после него). Препроцессор берет фактический аргумент, указанный при вызове макроса, и создает один маркер из этого аргумента и из маркера, который следует за ## или предшествует ##. Предположим, что у нас имеется список переменных от х1 до хЮО. Мы можем написать макрос с вызовом printx, который принимает в качестве аргумента значение от 1 до 100 и выводит значение соответствующей переменной. define printx(n) printf ("%i\n", x ## n) Часть x ## n указывает, что нужно взять маркеры, стоящие перед и после ## (соответственно букву х и аргумент п), и создать из них один маркер. Поэтому вызов

Поделиться:
Популярные книги

АН (цикл 11 книг)

Тарс Элиан
Аномальный наследник
Фантастика:
фэнтези
героическая фантастика
попаданцы
аниме
5.00
рейтинг книги
АН (цикл 11 книг)

Дважды одаренный. Том VI

Тарс Элиан
6. Дважды одаренный
Фантастика:
аниме
альтернативная история
фэнтези
фантастика: прочее
5.00
рейтинг книги
Дважды одаренный. Том VI

Мы – Гордые часть 8

Машуков Тимур
8. Стальные яйца
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Мы – Гордые часть 8

Законник Российской Империи. Том 4

Ткачев Андрей Юрьевич
4. Словом и делом
Фантастика:
городское фэнтези
альтернативная история
аниме
дорама
5.00
рейтинг книги
Законник Российской Империи. Том 4

Роза ветров

Кас Маркус
6. Артефактор
Фантастика:
городское фэнтези
аниме
фэнтези
5.00
рейтинг книги
Роза ветров

Развод с генералом драконов

Солт Елена
Фантастика:
фэнтези
5.00
рейтинг книги
Развод с генералом драконов

Оживший камень

Кас Маркус
1. Артефактор
Фантастика:
городское фэнтези
попаданцы
аниме
5.00
рейтинг книги
Оживший камень

Наследник

Майерс Александр
3. Династия
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Наследник

Последний Паладин. Том 10

Саваровский Роман
10. Путь Паладина
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Последний Паладин. Том 10

Законы Рода. Том 14

Андрей Мельник
14. Граф Берестьев
Фантастика:
аниме
фэнтези
эпическая фантастика
5.00
рейтинг книги
Законы Рода. Том 14

Излом

Осадчук Алексей Витальевич
10. Последняя жизнь
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Излом

Хозяин Теней 7

Петров Максим Николаевич
7. Безбожник
Фантастика:
аниме
фэнтези
фантастика: прочее
попаданцы
5.00
рейтинг книги
Хозяин Теней 7

Кодекс Охотника. Книга XVIII

Винокуров Юрий
18. Кодекс Охотника
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Кодекс Охотника. Книга XVIII

Проданная Истинная. Месть по-драконьи

Белова Екатерина
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Проданная Истинная. Месть по-драконьи