Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лабы / C++ / C++ / 09_функции_a5.doc
Скачиваний:
41
Добавлен:
17.04.2013
Размер:
175.1 Кб
Скачать

Пример 9.7.

#include <iostream.h>

swp(int *x, int *y);

void main()

{ int a, b;

cout<<»Введите значения a и b»;

cin>>a>>b;

swp(&a, &b);

cout<<»Измененные значения:a=»<<a<<”b=”<<b;

}

void swp(int *x, int *y)

// x и y – указатели, *x и *y – значения, на которые они указывают

{ int c;

c=*x;

x=y;

*y=c;

}

Пример 9.8. Рассмотрим функцию, которая находит среднее значение массива целых чисел. Для входа в функцию задано имя массива и количество его элементов. Результатом работы функции является среднее значение, которое передается при помощи оператора return.

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

cout<<»Среднее из заданных значений»<<mean (numbs, size)<<endl;

/* Находим среднее значение массива из n целых чисел.*/

int mean (int array [ ], int n)

{ int index;

long sum; /* Если массив содержит много элементов, сумма может оказаться довольно большой, поэтому используем тип long int */.

If (n>0)

{ for (index=0, sum=0; index<n; index++)

sum+=array [index];

return sum/n; // Возвращает int.

}

else

{cout<<”Нет массива.”<<endl;

return 0;

}

}

Перепишем эту же программу с использованием указателей. Объявим iPtr указателем на тип int и заменим элемент массива array[index] на соответствующее значение: *(iPtr+index).

Пример 9.9 Использование указателей для нахождения среднего значения массива n целых чисел.

Int mean (int *iPtr, int n)

{ intindex;

long sum;

if (n>0)

{ for (index=0, sum=0; index<n; index++)

sum+=*(iPtr+index);

return sum/n; // возвращает целое sum / n

}

else

{ cout<<”Нет массива”<<endl;

return 0;

}

}

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

Int iarray [10];

int *iPtr = iarray; // То же самое, что iPtr=&iarray[0].

В С++ указатели можно увеличивать или уменьшать. Указатель, увеличенный на 3, будет указывать на четвертый элемент массива (эквивалентно &array[3]). Другими словами, увеличивая указатель на единицу, мы в действительности увеличиваем адрес, который он представляет, на размер объекта связанного с ним типа.

Так как указателям типа voidне соответствует никакой тип данных, к ним нельзя применять арифметические операции.

Указатель можно индексировать точно так же, как массив. Компилятор в действительности преобразует индексацию в арифметику указателей: iarray[3]=10; представляется как *(iarray+3)=10;

Понятие ссылки

В С++ имеется несколько видоизмененная форма указателя, называемая ссылкой. Ссылка на некоторую переменную может рассматриваться как указатель, который при употреблении всегда разыменовывается. Однако для ссылки не требуется дополнительного пространства памяти: она является просто другим именем (псевдонимом) переменной.

Для определения ссылки применяется унарный оператор &.

Пример 9.10.

# include <iostream.h>

int value=10;

int &refval=value; // Ссылка на value

int main (void)

{ cout<<”value=”<<value<<endl;

refval+=5; // Модификация через ссылку

cout<<”value=”<<value<<endl;

cout<<”Адрес value равен “<<&value<<endl;

cout<<”Адрес refval равен “<<&refval<<endl;

return 0;

}

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

Пример 9.11.

# includе <iostream.h>

void Inc_val (int i) // Получает параметр-значение

{ i++; // Модификация не влияет на оригинал

}

void Inc_ptr (int *i) // Получает адрес оригинала

{(*i)++; // Модифицирует оригинал путем косвенной адресации

}

void Inc_ref (int & i) // Получает параметр-ссылку

{i++; // Модифицирует оригинал!

}

int main(void)

{ int j=10;

cout<<”j=”<<j<<endl;

Inc_val (j);

cout<<”После Inc_val (j) j = “<<j<<endl;

Inc_ptr (&j);

Cout<<”После Inc_ptr (j) j=”<<j<<endl;

Inc_ref (j);

Cout<<”После Inc_ref (j) j=”<<j<<endl;

return 0;

}

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

  1. вызывающей функции не требуется применять операцию взятия адреса (&);

  2. вызываемая функция избавляет от использования косвенных операций (*).

Ссылка может быть использована как тип, возвращаемый функцией. Это позволяет присваивать функции значение.

Пример 9.12. Ссылка как возвращаемый функцией тип.

#include <iostream.h>

const int arraySize = 0xF;

static int valArray[arraySize];

int &valueAt(int indx)

{ return valArray [indx];

}

int main (void)

{ for (int I=0; I<arraySize; I++)

valueAt (i)=1<<I;

for (I=0; I<arraySize; I++)

cout<<”Значение”<<I<<”=”<<valueAt(i)<<endl;

return 0;

}

Функцию valueAt(int) можно применять как для чтения элемента с определенным индексом, так и для присваивания нового значения этому элементу.

Соседние файлы в папке C++