ОБЪЕКТНО-ОРИЕНТИРОВАННОЕ ПРОГРАММИРОВАНИЕ В C++ (4-Е ИЗДАНИЕ) (часть 10) онлайн

Передача массивов

Начиная с главы 7, мы рассматривали многочисленные примеры, в которых мас- сивы передаются как аргументы в функции, при этом функция имела доступ к их элементам. До этой главы мы использовали только операции с массивами, так как нам были неизвестны указатели. Однако при передаче массива в функцию принято использовать указатели, а не просто операции массива. Рассмотрим это в программе PASSARR:

// passarr.cpp

// передача массива по указателю

#include <iostream>

using namespace std;

const int MAX = 5;            // количество элементов в массиве

 

int main ( )

{

  void centimize ( double* ); // прототип функции

 

  double varray [ MAX ] = { 10.0, 43.1, 95.9, 58.7, 87.3 };

 

  centimize( varray );        // переводим все элементы массива в сантиметры

 

  // покажем, что у нас получилось

  for ( int j = 0; j < MAX; j++ )

cout << "varray [ " << j << " ] = " << varray [ j ] << " сантиметров" << endl;

 

  return 0;

}

///////////////////////////////////////////////////////////

void centimize ( double* ptrd )

{

  for ( int j = 0; j < MAX; j++ )

    *ptrd++ *= 2.54;

}

 

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

void centimize ( double[ ] );

Записи double* и double [ ] эквивалентны, но синтаксис указателей использу- ется чаще.

Так как имя массива является его адресом, то нам нет надобности использо- вать операцию взятия адреса & при вызове функции:

centimize ( varray ); // передается адрес массива

В функции centimize() адрес массива присваивается переменной ptrd. Мы прос- то используем операцию увеличения для указателя ptrd, чтобы указать на все элементы массива по очереди:

*ptrd++ *= 2.54;

 

На рис. 10.7 показан доступ к массиву. А результат работы программы PASSARR будет следующим:

varray [ 0 ] - 25.4 сантиметров varray [ 1 ] - 109.474 сантиметров varray [ 2 ] - 243.586 сантиметров varray [ 3 ] - 151.638 сантиметров varray [ 4 ] - 221.742 сантиметров

main()  centimize ()

main() передает адрес varray в ptrd функции centimize()

centimlze() использует этот адрес для доступа ко всем элементам массива по очереди

Рис. 10.7. Доступ к массиву из функции

Рассмотрим вопрос синтаксиса: как узнать, что в выражении *ptrd++ увеличи- вается указатель, а не его содержимое? Другими словами, как компилятор ин- терпретирует это выражение: как *(ptrd++), что нам и нужно, или как (*ptrd)++? Здесь * (при использовании в качестве операции разыменования) и ++ имеют одинаковый приоритет. Однако операции одинакового приоритета различаются еще и другим способом: ассоциативностью. Ассоциативность определяет, как компилятор начнет выполнять операции, справа или слева. В группе операций, имеющих правую ассоциативность, компилятор выполняет сначала операцию, стоящую справа. Унарные операции * и ++ имеют правую ассоциативность, по- этому наше выражение интерпретируется как *(ptrd++) и увеличивает указатель, а не то, на что он указывает. Таким образом, сначала увеличивается указатель, а затем к результату применяется операция разыменования.

 

14