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

Int mean (int *iPtr, int n)

{ int index;

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

Контрольные вопросы

7. Каков допустимый уровень вложенности функции в языке С?

2. Как определить функцию? Что такое прототип функции? Всегда ли обязательно объявление прототипов?

3. Как передать информацию функции?

4. В чем разница между формальными и фактическими аргументами? Где описываются аргументы?

5. Где описываются локальные переменные функции?

6. Для чего служит оператор return? Обязательно ли его использование?

7. Проверьте, все ли правильно в следующем определении функции:

hallo (num)

{ int num, count;

for (count =1; count <= num; num++)

cout<<”Hello, my friend!”<<endl;

}

Варианты заданий

Номер варианта Задание
1, 21 Задать значения вещественным элементам массивов А = {ai| i = 0,1,…,7}, B = {bjЅj = 0,1,…,5}, C = {ckЅ k = 0,1,…,9}, D = {dnЅn = 0,1,…,9} и вычислить

 

Номер варианта Задание
2, 22 Задать значения целочисленным элементам массивов А = {aj| i = 0, 1,…, 8}, B = {bjЅj = 0, 1,…,5}, C = {ckЅ k = 0,1,…,6} и вычислить
3, 23   Задать значения целочисленным элементам массивов М = {mi Ѕi = 0, 1,…,7}, L = {ljЅj = 0, 1,…,6}, C = {ckЅ k = 0, 1,…,8} и вычислить
4, 24 Задать значения вещественным элементам массивов А = {aiЅ i = 0, 1,…, 6}, B = {bjЅj = 0, 1, 2, 3}, C = {ckЅ k = 0, 1, 2,…, 10} и вычислить
5, 25 Задать значения целочисленным элементам матриц А = {aij}, B = {bij}, где i = 0, 1, 2, 3; j = 0, 1, 2,…, 6 и сформировать массивы С и D, состоящие из максимальных элементов столбцов матриц А и В соответственно.
6, 26 Задать значения вещественным элементам массивов A = {ai} и B = {bi}, где i = 0, 1, 2,…,9 и вычислить элементы массивов X = {xi} и Y = {yi} по формулам:
7, 27 Задать значения целочисленным элементам матриц M = {mij} и N = {nij}, где i = 0, 1, 2,…, 7; j = 0, 1, 2,…, 5 и сформировать массивы С и D, состоящие из максимальных элементов строк матриц M и N соответственно.
8, 28 Задать значения вещественным элементам матриц А = {аij} и Q = {qij}, где i = 0, 1, 2,…, 6; j = 0, 1, 2,…, 4 и сформировать массивы B и R, состоящие из минимальных элементов столбцов матриц A и Q соответственно.
9, 29 Задать значения целочисленным элементам матриц P = {pij} и Q = {qij}, где i = 0, 1, 2,…, 4; j = 0, 1, 2,…, 7 и сформировать массивы R и T из сумм отрицательных элементов строк матриц P и Q соответственно.
10, 30 Задать значения вещественным элементам матриц С = {сij} и D = {dij}, где i = 0, 1, 2,…, 5; j = 0, 1, 2,…, 5 и сформировать массивы X и Y из произведений положительных элементов столбцов матриц C и D соответственно.
Задать значения целочисленным элементам матриц W = {wij} и Z = {zij}, где i = 0, 1, 2; j = 0, 1, 2,…, 7 и сформировать массивы T и S соответственно из элементов матриц W и Z, больших заданного числа Р.

 

 

Номер варианта Задание
Задать значения вещественным элементам матриц B = {bij} и D = {dij}, где i = 0, 1, 2,...,7; j = 0, 1, 2, 3, и сформировать массивы Y и Z, состоящие соответственно из элементов матриц B и D, меньших заданного числа R.
Задать значения вещественным элементам матриц Р = {рij}, Q = {qij}, где i = 0, 1, 2,..., 5; j = 0, 1, 2,..., 8 и сформировать массивы R и T, состоящие из минимальных элементов столбцов матриц P и Q соответственно.
Задать значения целочисленным элементам матриц A = {aij}, B = {bij}, где i = 0, 1, 2,..., 5; j = 0, 1, 2, 3 и вычислить элементы массивов X = {xij}, Y = {yij} по формулам:
Задать значения вещественным элементам массивов A = {ai}, B = {bi}, C = {ci}, где i = 0, 1, 2,...,6 и вычислить
Задать значения целочисленным элементам матриц A = {aij}, B = {bij}, где i = 0, 1; j = 0, 1, 2 и вычислить элементы матриц Y = {yij}, Z = {zij} по формулам
Задать значения целочисленным элементам массивов С = {сi} и D = {di}, где i = 0, 1, 2,..., 6 и вычислить элементы массивов S = {si} и T = {ti}, где i = 0, 1, 2,..., 6, по формуле:
Задать значения вещественным элементам массивов X = {xi| i = 0, 1, 2,..., 5}, Y = {yj| j = 0, 1, 2,..., 7}, Z = {zk| k = 0, 1, 2,..., 9}, и вычислить если
Задать значения вещественным элементам четырех квадратных матриц 5-го порядка и вычислить сумму квадратов значений той из матриц, у которой наибольшая сумма диагональных элементов.
Задать значения целочисленным элементам матриц А = {аij}, B = {bij}, где i = 0, 1, 2, 3, 4 j = 0, 1, 2, 3 и вычислить величины S=x0/x4+ x1/x3 + ... +x4/x0, T= y0/y4+ y1/y3+ ... + y4/y0, где xi, yi - максимальные элементы i-х строк матриц А и В соответственно.