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

ЖАНРЫ

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

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

Если написать функцию copyString с использованием указателей, то индексная переменная i не нужна. Версия с указателями показана в программе 13.13. #import < Foundation/Foundation.h> void copyString (char *to, char *from) { for (; *from != '\0'; ++from, ++to ) *to = *from; *to = '\0'; } int main (int arge, char *argv[]) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; void copyString (char *to, char *from); char string [] = "Копируемая строка"2; char string2[50]; copyString (string2, string 1); NSLog(@"%s", string2); copyString (string2, "Строка-константа"); NSLog(@"%s", string2); [pool drain]; return 0; }

Вывод

программы 13.13 Копируемая строка Строка-константа

В функции copyString определены два формальных параметра (to и from) как указатели на символы, а не на массивы символов, как в предыдущей версии copyString. Это показывает, каким образом эти две переменные будут использо-ваться в функции.

Затем происходит вход в цикл for (без начальных условий) для копирования строки, которую указывает параметр from (откуда) в строку, которую указывает параметр to (куда). На каждом шаге цикла выполняется увеличение указателей from и to на I. В результате указатель from указывает на следующий символ для копирования из исходной строки, и указатель to указывает место, в котором будет сохранен этот символ. Когда указатель from указывает на нуль-символ, происходит выход из цикла for. Затем функция помещает нуль-символ в конец скопированной строки.

В процедуре main функция copyString вызывается дважды. В первый раз в строку string2 копируется содержимое строки stringl, во второй раз в строку string2 копируется содержимое константной символьной строки. Константные символьные строки и указатели

Из copyString (string2, "Строка-константа");

следует, что если константная символьная строка передается как аргумент фун-кции, эта символьная строка фактически передается указателю. Это верно не только в данном случае. Обобщая, можно сказать, что если константная сим-вольная строка используется в Objective-C, то на эту символьную строку создается указатель.

Это может вызвать некоторую путаницу, но, как мы отмечали в главе 4, кон-стантные символьные строки называются строками встиле С (С-строками). Они не яатяются объектами. Объект константной символьной строки создается в том случае, если перед строкой поставлен знак например, @"This is okay", и мы не можем использовать один вид вместо другого.

Таким образом, если переменная textPtr объявлена как указатель на символ, char *textPtr;

оператор textPtr = "Символьная строка";

присваивает переменной textPtr указатель на константную символьную строку "Символьная строка". Будьте внимательны, чтобы отличать указатели на символь-ные строки от символьных массивов, поскольку приведенное выше присваивание нс подходит для символьного массива. Например, если определить text как массив символов с помощью следующего оператора char text[80];

то мы не сможем написать такой оператор, как text = "Это неправильно";

Единственный случай, когда Objective-C допускает такой тип присваивания для символьного массива —инициализация массива: char text[80] = "Это правильно";

При такой инициализации массива text не происходит создание указателя на символьную строку "Это правильно" внутри text. Вместо этого происходит запись самих символов с конечным нуль-символом в соответствующие элементы массива text.

Если text — это указатель на тип char, то в случае инициализации text с помо-щью оператора char *text = "Это правильно";

ему будет присвоен указатель на

символьную строку "Это правильно". Снова об операторах приращения (++) и уменьшения (--)

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

Операторы приращения и уменьшения можно использовать в выражениях, где присутствуют другие операторы. В таких случаях важно знать, как они действуют.

Операторы приращения (increment) и уменьшения (decrement) всегда по-мещаются перед соответствующими наращиваемыми и уменьшаемыми пере-менными. Например, для приращения переменной i достаточно написать: ++i;

Оператор приращения можно также поместить после переменной: i++;

Оба выражения допустимы, и оба дают одинаковый результат: увеличение на I значения i. В первом случае, когда ++ помещается перед операндом, операция увеличения называется преувеличением (pre-increment). Во втором случае, когда ++ помещается после операнда, операция увеличения называется посту-величением.

То же самое относится к оператору уменьшения. Поэтому оператор --i;

выполняет предуменыиение i, а оператор i--;

выполняет постуменьшение i. Оба дают одинаковый результат: вычитание 1 из значения i.

Если операторы приращения и уменьшения используются в более сложных выражениях, то отличия между пред- и пост-операторами могут быть существен-ными.

Предположим, что у нас есть две целые переменные: i и j. Если присвоить i значение 0 и затем написать оператор j = ++i;

то переменной j будет присвоено значение 1, а не 0. В случае оператора преду-величения переменная наращивается до того, как ее значение используется в выражении. В приведенном выше выражении значение i сначала увеличивается с 0 до 1, а затем ее значение присваивается переменной j, как в следующих двух операторах. ++i; i = i;

Если использовать оператор постувеличения j = i++;

значение i будут увеличено после того, как она будет присвоена переменной j. Если i было присвоено значение 0 перед выполнением оператора постувеличс- ния, то переменной j будет присвоено значение 0, и затем значение i будет уве-личено на 1, как в следующих операторах. j = i; ++i;

Еше один пример. Если i равна 1, то в результате оператора X = a[--i];

переменной х будет присвоено значение а[0], так как переменная i уменьшается до того, как ее значение используется для индексации а. Оператор x = a[i--];

присваивает х значение а[1], поскольку i уменьшается после того, как ее значение используется для индексации а.

Третий пример отличий между пред- и пост-операторами приращения и уменьшения. При вызове функции NSLog (@"%i", ++i);

происходит увеличение i, после чего ее значение передается функции NSLog, а при вызове NSLog (@"%i", i++);

увеличение i происходит после того, как ее значение передано этой функции. Таким образом, если значение i было равно 100, при первом вызове NSLog на терминал будет выведено 101, а при втором вызове NSLog — 100. В обоих случаях значение i будет равно 101 после выполнения оператора.

И последний пример. Если textPtr — указатель на тип char, то в выражении *(++textPtr)

textPtr сначала увеличивается на 1, а затем извлекается символ, на который ука-зывает textPtr. Однако в выражении *(textPtr++)

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