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

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

Жанры

Программирование на 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 указывает, что нужно взять маркеры, стоящие перед и после ## (соответственно букву х и аргумент п), и создать из них один маркер. Поэтому вызов

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

Старый, но крепкий 4

Крынов Макс
4. Культивация без насилия
Фантастика:
уся
фэнтези
5.00
рейтинг книги
Старый, но крепкий 4

Точка Бифуркации X

Смит Дейлор
10. ТБ
Фантастика:
аниме
фэнтези
попаданцы
5.00
рейтинг книги
Точка Бифуркации X

Живое проклятье

Алмазов Игорь
3. Жизнь Лекаря с нуля
Фантастика:
попаданцы
альтернативная история
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Живое проклятье

Древесный маг Орловского княжества 6

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

Здравствуй, 1985-й

Иванов Дмитрий
2. Девяностые
Фантастика:
альтернативная история
5.25
рейтинг книги
Здравствуй, 1985-й

Газлайтер. Том 9

Володин Григорий
9. История Телепата
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Газлайтер. Том 9

Черный Маг Императора 14

Герда Александр
14. Черный маг императора
Фантастика:
аниме
сказочная фантастика
фэнтези
фантастика: прочее
попаданцы
5.00
рейтинг книги
Черный Маг Императора 14

Виконт. Книга 4. Колонист

Юллем Евгений
Псевдоним `Испанец`
Фантастика:
фэнтези
попаданцы
аниме
7.50
рейтинг книги
Виконт. Книга 4. Колонист

Точка Бифуркации III

Смит Дейлор
3. ТБ
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Точка Бифуркации III

Вторая жизнь майора. Цикл

Сухинин Владимир Александрович
Вторая жизнь майора
Фантастика:
героическая фантастика
боевая фантастика
попаданцы
5.00
рейтинг книги
Вторая жизнь майора. Цикл

Вечный. Книга V

Рокотов Алексей
5. Вечный
Фантастика:
боевая фантастика
попаданцы
рпг
5.00
рейтинг книги
Вечный. Книга V

Печать пожирателя 2

Соломенный Илья
2. Пожиратель
Фантастика:
городское фэнтези
попаданцы
аниме
сказочная фантастика
5.00
рейтинг книги
Печать пожирателя 2

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

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

Неудержимый. Книга XXVIII

Боярский Андрей
28. Неудержимый
Фантастика:
аниме
фэнтези
попаданцы
5.00
рейтинг книги
Неудержимый. Книга XXVIII