пользователей: 28280
предметов: 12134
вопросов: 228408
Конспект-online
РЕГИСТРАЦИЯ ЭКСКУРСИЯ

Массивы как параметры функций

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

Использование массива как параметра функции не вызывает ни каких трудностей. Как было сказано ранее, массив в подпрограмму всегда передаётся по адресу, поэтому достаточно при вызове функции указать адрес начала массива или адрес того элемента, начиная с которого предполагается обрабатывать массив.

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

Возможный вариант решения:

#include <iostream>

using namespace std;

void print(int x[], int n);

int main()

{

   const int n = 5;

   int x[n] = {3, 5, 1 ,7, 4};

   print(x, n);

   return 0;

}

void print(int x[], int n)

{

   cout << "Massiv:" << endl;

   for(int i = 0; i < n; i++)

      cout << x[i] << endl;

}

При вызове функции оператором

print(x, n);

в неё передаётся адрес начала массива x и количество элементов n. Количество элементов n передаётся по значению и здесь всё должно быть понятно, но вот с передачей самого массива может быть некоторое непонимание, которое необходимо устранить.

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

print(&x[0], n);

С учётом того, что массив в подпрограмму чаще всего передаётся весь и с начала, разработчики языка запись вида &x[0] сократили до x, т.е. обращение к массиву по имени эквивалентно обращению по адресу к элементу с индексом 0.

В заголовке функции

void print(int x[], int n) // 1-й вариант

два формальных параметра. Запись x[] говорит о том, что в подпрограмму передаётся именно массив.

Заголовок может выглядеть и так:

void print(int *x, int n) // 2-й вариант

Массив передаётся по адресу, поэтому и записываем первый параметр как адрес на объект типа int. Этот объект-указатель принимает адрес того элемента массива, который вычисляется в вызывающей функции (например, в main()).

Какую форму использовать? Это дело вкуса. Компилятор рассматривает 1-й вариант как эквивалент 2-го, хотя для человека нагляднее именно 1-й вариант. По нему видно, что формальный параметр — это именно массив, а не указатель, например, на одиночный элемент.

Трактовка при вызове x как &x[0] позволяет при необходимости передать в подпрограмму не весь массив, а только его часть, начиная с какого-либо адреса. Например, вызов

print(&x[2], n - 2);

приводит к выводу на экран монитора трёх элементов массива, начиная с элемента с индексом 2. При этом сама функция не требует каких либо доработок. В этом плане языки С/С++ гораздо удобнее многих других языков. Так, в Паскале или Бейсике пришлось бы передавать в подпрограмму ещё один параметр — номер элемента, с которого необходимо начать обработку массива, а затем этот номер использовать в операторе цикла.

Многомерные массивы как параметры функций

Для многомерных массивов (имеются ввиду массивы трёхмерные, четырёхмерные и так далее, т.е. с размерностью более двух) мы имеем те же проблемы, что и для матриц. Если передавать, к примеру, обычный трёхмерный массив в подпрограмму, то прототип функции может выглядеть так:

// Прототип функции печати трёхмерного массива

void Print(int V[][N][M], int k, int n, int m);

Здесь необходимы уже две константы: N и M. Недостатки такой функции те же, что и при передачи в подпрограмму матрицы, т.е. отсутствие универсальности.

Решение проблемы — так же в использовании динамических массивов:

// Прототип функции печати трёхмерного динамического массива

void Print(int ***V, int k, int n, int m);

Универсальность достигнута, но в ущерб скорости работы программы.


27.12.2014; 11:28
хиты: 34
рейтинг:0
Точные науки
информатика
Языки программирования
для добавления комментариев необходимо авторизироваться.
  Copyright © 2013-2018. All Rights Reserved. помощь