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

Передача массивов в функции

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

// salefunc.cpp

// передача массива в виде параметра

#include <iostream>

#include <iomanip>

using namespace std;

const int DISTRICTS = 4;

const int MONTHS = 3;

void display ( double [ DISTRICTS ][ MONTHS ] );

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

int main ( )

{

  double sales [ DISTRICTS ][ MONTHS ] =

  {

    {  1432.07,   234.50,   654.01 },

    {   322.00, 13838.32, 17589.88 },

    {  9328.34,   934.00,  4492.30 },

    { 12838.29,  2332.63,    32.93 }

  };

 

  display ( sales );

  cout << endl;

return 0;

}

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

// display ( )

// функция для вывода на экран массива

void display ( double funsales [ DISTRICTS ][ MONTHS ] )

{

  int d, m;

 

  cout << "\n\n";

  cout << "                        Месяц\n";

  cout << "                1         2         3";

 

  for ( d = 0; d < DISTRICTS; d++ )

  {

    cout << "\nОтдел " << d + 1;

    for ( m = 0; m < MONTHS; m++ )

    {

      cout << setiosflags ( ios::fixed ) << setw ( 10 )

           << setiosflags ( ios::showpoint ) << setprecision ( 2 )

           << funsales [ d ] [ m ];

    }

  }

}

 

Объявление функции с аргументами в виде массивов

В объявлениях функции массивы-аргументы представлены типом данных и раз- мером. Вот объявление функции display();

void display ( double [ DISTRICTS ][ MONTHS ] );

Нa самом деле здесь есть один необязательный элемент. Следующее объяв- ление работает так же:

void display ( double [ ][ MONTHS ] );

Почему функции не нужно значение первой размерности? Вспомним, что двумерный массив — это массив массивов. Функция сначала рассматривает аргу- мент как массив отделов. Ей не важно знать, сколько отделов, но нужно знать, насколько велики элементы, представляющие собой отделы, так как тогда она сможет вычислить, где находится каждый элемент (умножая количество байтов, приходящееся на один элемент, на индекс нужного элемента). Поэтому мы мо- жем сообщить функции размер массива MONTHS, но не сообщать, сколько таких массивов находится в массиве DISTRICTS.

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

void somefunc ( int elem [ ] );

Вызов функции с массивом в качестве аргумента

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

display ( sales );

 

Это имя (в нашем случае sales) в действительности представляет собой адрес массива в памяти. Мы не будем объяснять адреса детально до главы 10 «Указа- тели», но рассмотрим несколько общих вопросов.

Использование адресов для массивов-аргументов похоже на использование аргумента ссылки, при котором значения элементов массива не дублируются (копируются) в функции. (Смотрите обсуждение ссылочных аргументов в гла- ве 5 «Функции».) Вместо этого функция работает с оригинальным массивом, хотя ссылается на него, используя другое имя. Эта система используется для массивов, потому что они могут быть очень большими; дублирование массива для каждой вызывающей его функции может отнимать много времени и про- странства в памяти.

Однако адрес — это не то же самое, что и ссылка. С именем массива не ис- пользуется амперсанд (&) при объявлении функции. Пока мы не изучили указа- тели, примите на веру, что массивы передаются в функцию только с использо- ванием их имени и что функция работает при этом с оригиналом массива, а не с его копией.

Определение функции с массивом в качестве аргумента

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

void display ( double funsales [ DISTRICTS ][ MONTHS ] )

При записи аргумента-массива используются тип его данных, имя массива и его размерности. Имя массива, используемое при определении функции (в на- шем случае funsales), может отличаться от имени массива, который затем будет использоваться в функции (sales), но оба этих имени ссылаются на один и тот же массив. Должны быть определены все размерности массива (исключая пер- вую в некоторых случаях); они нужны функции для правильного обращения к элементам массива.

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

funsales [ d ][ m ];

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

 

 

10