Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Подбельский Фомин_Программирование на языке СИ_...doc
Скачиваний:
356
Добавлен:
10.08.2019
Размер:
53.81 Mб
Скачать

5.2. Указатели в параметрах функций Указатель-параметр.

Указатель-параметр. В предыдущем параграфе мы достаточно подробно рассмотрели механизм передачи параметров при вызове функций. Схема передачи параметров по значениям не оставляет никаких надежд на возможность непосредственно изменить фактический параметр за счет выполнения операторов тела функции. И это действительно так. Объект вызывающей программы, использованный в качестве фактического параметра, не может быть изменен из тела функции. Однако существует косвенная возможность изменять значения объектов вызывающей программы действиями в вызванной функции. Эту возможность обеспечивает аппарат указателей. С помощью указателя в вызываемую функцию можно передать адрес любого объекта из вызывающей программы. С помощью выполняемого в тексте функции разыменования указателя мы получаем доступ к адресуемому указателем объекту из вызывающей программы.

Тем самым, не изменяя самого параметра (указатель-параметр постоянно содержит только адрес одного и того же объекта), можно изменять объект вызывающей программы.

Продемонстрируем изложенную схему на простом примере:

Результат выполнения программы:

Параметр функции positive() - указатель типа int *. При обращении к ней из основной программы main( ) в качестве фактического параметра используется адрес &k переменной типа int. Внутри функции значение аргумента (т.е. адрес &k) "записывается" в участок памяти, выделенный для указателя int *m. Разыменование *m обеспечивает доступ к тому участку памяти, на который в этот момент "смотрит" указатель m. Тем самым в выражении

все действия выполняются над значениями той переменной основной программы (int k), адрес которой (&k) использован в качестве фактического параметра.

Графически иллюстрирует взаимосвязь функции positive( ) и основной программы рис. 5.1. При обращении к функции positive( ) она присваивает абсолютное значение той переменной, адрес которой использован в качестве ее параметра.

Основная программа Функция positive ( )

Рис. 5.1. Схема "настройки" параметра-указателя

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

Здесь в форматной строке спецификаторы преобразования %ld и %lе обеспечивают ввод (чтение) от клавиатуры соответственно значений типов long int и double. Передача этих значений переменным long l и double d обеспечивается с помощью их адресов &l и &d, которые используются в качестве фактических параметров функции scanf( ).

Имитация подпрограмм.

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

void print(int gg, int mm, int) и void Real_Time(void),

каждая из которых очень похожа на подпрограммы других языков программирования.

К сожалению, в языке Си имеется еще одно препятствие для непосредственного использования функции в роли подпрограммы — это рассмотренная выше передача параметров только значениями, т.е. передаются значения переменных, а не их адреса. Другими словами, в результате выполнения функции нельзя изменить значения ее фактических параметров. Таким образом, если Z( ) - функция для вычисления периметра и площади треугольника по длинам сторон Е, F, G, то невозможно, записав оператор-выражение Z(E, F, G, PP, SS); получить результаты (периметр и площадь) в виде значений переменных РР и SS. Так как параметры передаются только значениями, то после выполнения функции Z( ) значения переменных РР и SS останутся прежними.

Возможно следующее решение задачи. В определении функции параметры, с помощью которых результаты должны передаваться из функции в точку вызова, описываются как указатели. Тогда с помощью этих указателей может быть реализован доступ из тела функции к тем объектам вызывающей программы, которые адресуются параметрами-указателями. Для пояснения сказанного рассмотрим следующую программу:

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

Имитация подпрограммы (функция) для вычисления периметра и площади треугольника:

Пример результатов выполнения программы: