|
Программирование >> Структурное программирование
Первый вызов кгикдой функции: Значения при входе в staticArraylnit: arrayl[0] = О arrayl[l] = О arrayl[2] = О Значения при выходе из staticArraylnit: arrayl[0] = 5 arrayl[l] = 5 arrayl[2] = 5 Значения при входе в automaticArraylnit: аггау2[0] = 1 аггау2[1] = 2 аггау2[2] = 3 Значения при выходе из automaticArraylnit: аггау2[0] = б аггау2[1] = 7 аггау2[2] = 8 Второй вызов каяцой функции: Значения при входе в staticArraylnit: arrayl[0] = 5 arrayl[l] = 5 arrayl[2] = 5 Значения при выходе из staticArraylnit: arrayl[0] = 10 arrayl[l] = 10 arrayl[2] = 10 Значения при входе в automaticArraylnit: аггау2[0] = 1 аггау2[1] = 2 аггау2[2] = 3 Значения при выходе из automaticArraylnit: аггау2[0] = б аггау2[1] = 7 аггау2[2] = 8 Рис. 4.13. Сравнение присваивания начальных значений массиву типа static и автоматическому массиву (часть 2 из 2) 4.5. Передача массивов в функции Чтобы передать массив в качестве аргумента в функцию, укажите имя массива без каких-либо квадратных скобок. Например, если массив hourlyTemperatures объявлен как int hourlyTemperatures[24]; ТО оператор вызова функции modifyArray(hourlyTemperatures, 24); передает массив hourlyTemperatures и его размер функции modifyArray. При передаче массива в функцию его размер часто передается, чтобы функция могла обрабатывать заданное число элементов в массиве. В главе 8, когда мы познакомимся с классом Array, мы будем встраивать размер массива внутрь типа, определяемого пользователем - каждый объект Array, который мы создадим, будет знать свой собственный размер. Таким образом, при передаче объекта Array функции нет необходимости передавать ей в качестве аргумента размер массива. С-Ь-Ь автоматически передает массивы функциям, используя моделируемый вызов по ссылке - вызываемые функции могут изменять значения элементов в исходных массивах источника вызова. Значение имени массива является адресом первого элемента массива. Поскольку в функцию передается начальный адрес массива, вызываемая функция знает, где хранится массив. Поэтому, когда вызываемая функция модифицирует элементы массива в теле функции, она модифицирует реальные элементы массива в их истинных ячейках памяти. Совет по повышению эффективности 4.2 Передача массивов с помощью моделируемго вызова по ссылке ощутимо влияет на производительность. Если бы массивы передавались по значению, передавалась бы копия каждого элемента. Для больших, часто передаваемых массивов это привело бы к значительному потреблению времени и памяти для хранения копий массивов. Замечание по технике программирования 4.2 Передавать массив по значению можно, используя простой прием, который мы объясним в главе 6. Хотя массивы как целое передаются моделируемым вызовом по ссылке, отдельные элементы массива передаются вызовом по значению подобно простым переменным. Такие отдельные простые элементы данных называются скалярами или скалярными параметрами. Чтобы передать в функцию элемент массива, используйте индексированное имя элемента массива как аргумент в вызове функции. В главе 5 мы покажем, как можно моделировать вызов по ссылке для скаляров (т.е. отдельных переменных и элементов массива). Чтобы функция могла принять массив, переданный через вызов функции, список параметров функции должен указывать на необходимость принятия массива. Например, заго.иовок функции modifyArray мог бы быть записан как void modifyArray(int b[], int arraySize) указывая, что modifyArray ожидает принятия массива целых чисел в параметре Ь, и количество элементов массива в параметре arraySize. Размер массива в квадратных скобках указывать не нужно. Если он включен, компилятор его проигнорирует. Поскольку массивы передаются моделируемым вызовом по ссылке, то вызываемая функция, используя имя массива Ь, в действительности будет работать с истинным массивом в источнике вызова (массив hourlyTemperatures в предыдущем вызове). В главе 5 мы познакомимся с другими формами записи, указывающими, что функция принимает массив. Как мы увидим, эти записи основаны на тесных связях между массивами и указателями. Отметим необычный вид прототипа функции для modifyArray void modifyArray (int [], int); Этот прототип мог бы быть записан в виде void modifyArray (int anyArrayName[], int anyVariableName) HO, как мы узнали в главе 3, компиляторы С+Л- игнорируют имена переменных в прототипах. Хороший стиль программирования 4.4 Некоторые программисты, чтобы сделать программу понятнее, включают имена переменных в функции прототипов. Компиляторы игнорируют эти имена. Напомним, что прототип сообщает компилятору количество аргументов и типы каждого аргумента (в порядке их ожидаемого появления). Замечание по технике программирования 4.3 Для предотвращения модификации исходного массива внутри тела функции можно в определении функции применять к параметру массив спецификатор типа const . Это еще один пример принципа наименьших привилегий. Функциям не должно быть позволено модифицировать массивы без крайней необходимости. Передача функциям массивов и их отдельных элементов tinclude <iostream.h> tinclude <iomanip.h> void modifyArray(int [ ], int); необычный вид прототипа void modifyElement(int); main () { const int arraySize = 5; int a[arraySize] = {0, 1, 2, 3, 4}; Программа на рис. 4.14 демонстрирует различие между передачей всего массива и его отдельных элементов. Программа сначала печатает пять элементов массива целых чисел а. Далее массив а и его размеры передаются функции modifyArray, где каждый элемент массива а умножается на 2. Затем а повторно печатается в main. Как показывают выходные данные, элементы а действительно модифицируются функцией modifyArray. Затем программа печатает значение а[3] и передает его функции modifyElement. Функция modify Element умножает свой аргумент на 2 и печатает его новое значение. Заметим, что при повторной печати элемента а[3] в main он не модифицировался, потому что отдельные элементы массива передаются вызовом по значению. В ваших программах возможна ситуация, когда функции нельзя позволять модифицировать элементы массива. Поскольку массивы всегда передаются моделируемым вызовом по ссылке, модификацией значений в массиве управлять затруднительно. С-Н- имеет спецификацию типа const для предотвращения модификации значений массива в функции. Когда параметр массив предварен спецификатором const, элементы массива в теле функции становятся постоянными и любая попытка модифицировать элементы массива в теле функции приводит к ошибке при трансляции. Сообщение об этой ошибке дает программисту возможность исправить программу так, чтобы она не пыталась модифицировать элементы массива. Программа на рис. 4.15 демонстрирует спецификацию const. Функция tryToModifyArray определяется с параметром const int b[ ], который указывает, что массив Ъ - постоянный и не может быть модифицирован. В выходных данных показаны сообщения об ошибках, вырабатываемые компилятором Borland С-Н-. Каждая из трех попыток функции модифицировать элементы массива приводит к ошибке компилятора Постоянный объект не может быть модифицирован . Спецификация const будет еще раз обсуждаться в главе 7.
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |