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

ЖАНРЫ

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

Передача всего массива функции или методу выполняется иначе. При вызове функции или метода нужно указать только имя этого массива (без индексов). Например, если grade_scores был объявлен как массив, содержащий 100 эле-ментов, выражение minimum (grade_scores)

будет передавать все 100 элементов, содержащихся в массиве grade_score$, функции с именем minimum. Конечно, функция minimum должна ожидать передачи всего массива как ар|умента и иметь соответствующее объявление формального параметра.

Следующая функция ищет минимальное целое значение в массиве с ука-занным количеством элементов. // Функция для поиска минимума в массиве int minimum (int values[], int numElements) { int minValue, i; minVaiue = values[0]; for (i = 1; i < numBements; ++i) if ( values[i] < minValue ) minValue = values[i]; return (minValue); }

В

соответствии с определением, функция minimum принимает два аргумента. Первый аргумент — это массив, минимум значений которого мы хотим найти, а второй аргумент — это число элементов в данном массиве. Прямоугольные скобки, которые непосредственно следуют после values в заголовке функции, информируют компилятор Objective-C, что values — это массив с целыми значе-ниями. Компилятору не нужен размер этого массива.

Формальный параметр numElements используется как верхний предел в опе-раторе for. С помощью оператора for выполняется перебор всего массива от элемента values[1] до последнего элемента vaiues[numElements-1].

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

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

Элемент многомерного массива можно передавать функции или методу как обычную переменную или элемент одномерного массива. В строке result = squareRoot (matrix[i][j]);

происходит вызов функции squareRoot с передачей в качестве аргумента значе-ния, содержащегося в matrix[i][j].

В качестве аргумента можно передать весь многомерный массив так же, как одномерный массив: нужно просто указать имя самого массива. Например, если матрица measuredValues объявлена как двумерный массив с целыми значениями, то оператор Objective-C scalarMultipiy (measuredValues, constant);

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

Мы уже говорили, что в случае объявления одномерного массива как фор-мального параметра нам не нужен конкретный размер массива. Мы просто ис-пользуем пару прямоугольных скобок, чтобы информировать компилятор Objective-C, что параметр является массивом. В случае многомерных массивов это применимо лишь отчасти. Для двумерного массива можно не указывать число строк массива, но объявление должно содержать число столбцов массива. Оба объявления int arrayValues[100][50]

и int arrayValues[][50]

являются допустимыми для массива формального параметра с именем arrayValues, который содержит 100 строк и 50 столбцов. Однако оба объявления int arrayValues[100][]

и int arrayValues[][]

не

являются допустимыми, поскольку необходимо указать число столбцов мас-сива. 13.3. Структуры

Помимо массивов, язык Objective-C содержит еще одно средство группирования элементов — структуры.

Предположим, что нам нужно нам нужно сохранить внутри программы дату (например, 18/07/09), чтобы использовать ее для заголовка результатов программы или для вычислений. Обычный способ сохранения даты — это присвоить месяц целой переменной с именем month, день — целой переменной day и год — целой переменной year. Поэтому здесь вполне подойдут операторы int month = 7, day = 18, year = 2009;

Но как быть, если в программе требуется сохранять несколько дат? Следо-вало бы сгруппировать эти наборы из трех переменных.

В языке Objective-C мы можем определить структуру с именем date (дата), которая состоит из трех компонентов, представляющих месяц, день и год. Син-таксис такого определения достаточно очевиден. struct date { int month; int day; int year; };

Только что определенная структура date содержит три целых компонента с именами month, day и year. Такое определение даты — новый тип переменных, переменные теперь можно объявлять с типом struct date, как в следующем опре делении: struct date today;

Мы можем определить переменную такого же типа purchaseDate (дата покупки) с помощью отдельного определения struct date purchaseDate;

или просто включить оба определения в одну строку: struct date today, purchaseDate;

В отличие от переменных типа int, float или char, при работе со структурными переменными требуется специальный синтаксис. Для доступа к компоненту структуры нужно указать имя структурной переменной, после которого следует точка (она называется оператором «точка» — dot operator) затем имя компо нента структуры. Например, чтобы задать значение 21 для компонента day переменной today, нужно написать today.day = 21;

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

Вы можете возразить, что мы уже использовали, казалось бы, такой же опе-ратор для вызова свойства объекта. Вспомним, что оператор myRect.width = 12;

вызывает метод-установщика (с именем sefWidth) объекта класса Rectangle, передавая ему значение аргумента 12. Здесь нет никакой путаницы: компилятор сам определяет, что находится справа от оператора «точка», — структура или объект, — и выполняет соответствующую обработку.

Вернемся к примеру struct date, чтобы задать значение 2010 для компонента year в структуре today. today.year = 2010;

И, наконец, чтобы проверить, что значение month равно 12, можно исполь-зовать оператор if (today, month == 12 ) next_month = 1;

В программе 13.6 реализуется то, что мы обсуждали выше. #import <Foundation/Foundation.h> int main (int arge, char *argv[]) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; struct date { int month; int day; int year; }; struct date today; today.month = 9; today.day = 25; today.year = 2009; NSLog (@"Today’s date is %i/%i/%.2i.", today.month, today.day, today.year % 100); [pool drain]; return 0; }

Вывод программы 13.6 Today’s date is 9/25/09. (Текущая дата - 25.9.09)

В первом операторе внутри main определяется структура с именем date, которая состоит из трех целых компонентов: month, day и year. Во втором операторе объявляется переменная today с типом struct date. Таким образом, в первом опе-раторе просто определяется, как выглядит структура даты для компилятора Objective-C, и не требуется никакого резервирования памяти внутри компьютера. Во втором операторе объявляется переменная типа struct date, и здесь происходит резервирование памяти для хранения трех целых компонентов структурной переменной today.

Поделиться с друзьями: