Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
PYaVU_s.doc
Скачиваний:
44
Добавлен:
24.02.2016
Размер:
665.09 Кб
Скачать
      1. Фактические аргументы

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

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

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

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

  • если объявлен список типов аргументов, то для каждого фактического аргумента вызова функции выполняются обычные арифметические преобразования для соответствующего типа, объявленного в списке типов аргументов и для фактических аргументов. Фактический аргумент приводится к этому типу. Затем тип преобразованного выражения сравнивается с типом соответствующего формального параметра, который задан в заголовке определения функции. Перед сравнением формальные параметры также подвергаются обычным арифметическим преобразованиям. Приведения типов не производится, но компилятор выдает все предупреждения, как будто бы выражение присваивается формальному параметру;

  • если список типов аргументов не объявлен, или если фактических аргументов больше, чем задано имен-типов в списке типов аргументов, то обычные арифметические преобразования производятся для каждого аргумента, не имеющего соответствующего имени-типа;

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

Тип каждого формального параметра также подвергается обычным арифметическим преобразованиям. Преобразованный тип каждого формального параметра определяет, каким образом интерпретируются аргументы в стеке. Еcли тип формального параметра не соответствует типу фактического параметра, то данные в стеке могут быть проинтерпретированы неверно.

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

Пример:

main ()

{

void swap (int *, int *);

int x, y;

.

.

.

swap (&x,&y);

}

void swap (int *a,int *b)

{

int t;

t=*a;

*a=*b;

*b=t;

}

В примере функция swap объявлена в main как функция с двумя аргументами типа указателей на int. Формальные параметры a и b объявлены так же, как указатели на целые величины. При вызове функции

swap(&x,&y)

адрес x запоминается в a и адрес y запоминается в b. Теперь два имени или "синонима" существует для одной и той же ячейки. Ссылки *a и *b в функции swap действуют точно так же, как x и y в main. Присваивание внутри функции swap изменяет содержимое x и y. Компилятор проведет проверку типов аргументов при вызове swap, поскольку имеется список типов аргументов в forward-объявлении swap. Типы фактических аргументов соответствуют списку типов аргументов и списку формальных параметров.