Указатель в качестве параметра цикла

Параметром цикла может быть переменная-указатель.

void MySum2(int* ar, unsigned size, int &S)

{ int *p=ar; S=0;

for (; p<= ar+(size-1); p++) S+=*p;

}

Если бы дополнительно указатель p для цикла не использовали, а ограничились бы только переменной ar, то мы потеряли бы доступ к началу массива, то есть его адрес. Более того, для статического массива адрес его начала (имя массива) компилятор не разрешит менять. Поэтому и в одном и в другом случаях надо объявить и использовать другой указатель (в функции таким является p) для использования его в цикле.

Можно цикл записать и так: for (; p<=&ar[size-1]; p++) S+=*p; Вариант, записанный в функции, лучше, так как мы “помогли компьютеру” найти адрес последнего элемента массива и не требуем, чтобы система преобразовывала индексное выражение. Можно объявить и проинициализировать ещё один указатель int *q=ar +size-1; и использовать его в заголовке цикла: for (; p<=q; p++) S+=*p;

Правильно будет работать и следующий вариант функции

void MySum3 (int *ar, unsigned size, int *uS)

{ int *p, *q=&ar[0]+size-1;

for (*uS=0, p=ar; p<=q;p++) *uS+=*p;

}

Здесь начальное значение указателя p определили в заголовке цикла, который можно записать и так: for (*uS=0, p=&ar[0]; p<=q; p++) … Но вариант в функции компьютеру больше понравится. Подумайте, почему.Кроме этого, результат функции получаем с помощью указателя uS. Поэтому в тексте функции для uS используется операция “*”.

Заметим, что во всех этих вариантах вместо условия p<= ar+size-1; в заголовке цикла можно записать p< ar+size;, и такой вариант будет правильно работать. Но так как ar+size — это адрес “не нашей”, то есть не принадлежащей нашему массиву ячейки, то первое условие в виде нестрогого неравенства предпочтительнее.


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: