Главная » Просмотр файлов » М. Бен-Ари - Языки программирования. Практический сравнительный анализ (2000)

М. Бен-Ари - Языки программирования. Практический сравнительный анализ (2000) (1160781), страница 20

Файл №1160781 М. Бен-Ари - Языки программирования. Практический сравнительный анализ (2000) (М. Бен-Ари - Языки программирования. Практический сравнительный анализ (2000)) 20 страницаМ. Бен-Ари - Языки программирования. Практический сравнительный анализ (2000) (1160781) страница 202019-09-19СтудИзба
Просмтор этого файла доступен только зарегистрированным пользователям. Но у нас супер быстрая регистрация: достаточно только электронной почты!

Текст из файла (страница 20)

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

Ada

X := Proc_1(Parm => Y) + Proc_2(Parm => Z);

7.3. Передача параметров подпрограмме

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

Давайте начнем с данного выше определения: значение фактического па­раметра передается формальному параметру. Формальный параметр — это просто переменная, которая объявлена внутри подпрограммы, поэтому, оче­видно, нужно копировать значение фактического параметра в то место памя­ти, которое выделено для формального параметра. Этот механизм называется

«семантикой copy-in » («копирование в») или «вызовом по значению» (call-by-value). На рисунке 7.1 показана семантика copy-in для процедуры:

procedure Proc(F: in Integer) is

begin

Ada

... ;

end Proc;

и вызова:

Ada

Proc(2+3*4);

Преимущества семантики copy-in:

• Copy-in является самым надежным механизмом передачи параметров. Поскольку передается только копия фактического параметра, подпро­грамма никак не может испортить фактический параметр, который, не­сомненно, «принадлежит» вызывающей программе. Если подпрограмма изменяет формальный параметр, изменяется только копия, а не ориги­нал.

• Фактические параметры могут быть константами, переменными или вы­ражениями.

• Механизм copy-in может быть очень эффективным, потому что началь­ные затраты на копирование делаются один раз, а все остальные обраще­ния к формальному параметру на самом деле являются обращениями к локальной копии. Как мы увидим в разделе 7.7, обращение к локальным переменным чрезвычайно эффективно.

Если семантика copy-in настолько хороша, то почему существуют другие ме­ханизмы? дело в том, что часто мы хотим изменить фактический параметр, несмотря на тот факт, что такое изменение «небезопасно»:

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

• Кроме того, цель выполнения подпрограммы может состоять в моди­фикации данных, которые ей передаются, а не в их вычислении. Обычно это происходит, когда подпрограмма обрабатывает структуру данных. Например, подпрограмма, сортирующая массив, не вычисляет значение; ее цель состоит только в том, чтобы изменить фактический параметр. Нет никакого смысла сортировать копию массива!

• Параметр может быть настолько большим, что копировать его неэффек­тивно. Если copy-in используется для массива из 50000 целых чисел, мо­жет просто не хватить памяти, чтобы сделать копию, или затраты на ко­пирование будут чересчур большими.

Первые две ситуации легко разрешить с помощью семантики copy-out («копирование из»). Фактический параметр должен быть переменной, а под­программе передается адрес фактического параметра, который она сохраняет. Для формального параметра используется временная локальная переменная, и значение должно быть присвоено формальному параметру, по крайней ме­ре, один раз во время выполнения подпрограммы. Когда выполнение под­программы завершено, значение копируется в переменную, на которою ука­зывает сохраненный адрес. На рисунке 7.2 показана семантика copy-out для следующей подпрограммы:

procedure Proc(F: out Integer) is

begin

Ada

F := 2+3*4; -- Присвоение параметру

end Proc;

A: Integer;

Proc(A); -- Вызов процедуры с переменной

Когда нужно модифицировать фактический параметр, как, например, в sort, можно использовать семантику copy-in/out фактический параметр копирует-

ся в подпрограмму, когда она вызывается, а результирующее значение копи­руется обратно после ее завершения.

Однако механизмы передачи параметров на основе копирования не могут решить проблему эффективности, связанную с «большими» параметрами. Ре­шение, которое известно как «вызов по ссылке» (call-by-reference) или «семан­тика ссылки» (reference cemantics), состоит в том, чтобы передать адрес факти­ческого параметра и обращаться к параметру косвенно (см. рис. 7.3). Вызов подпрограммы эффективен, потому что для каждого параметра передается только указатель небольшого, фиксированного размера; однако обращение к параметру может оказаться неэффективным из-за косвенности.

Чтобы получить доступ к фактическому параметру, нужно загрузить его ад­рес, а затем выполнить дополнительную команду для загрузки значения. Обра­тите внимание, что при использовании семантики ссылки (или copy-out), фактический параметр должен быть переменной, а не выражением, так как ему будет присвоено значение.

Другая проблема, связанная с вызовом по ссылке, состоит в том, что может возникнуть совмещение имен (aliasing), т. е. может возникнуть ситуация, в ко­торой одна и та же переменная известна под несколькими именами.

В следующем примере внутри функции f переменная global получает алиас (т. е. альтернативное имя) *parm:

C

int global = 4;

inta[10];

int f(int *parm)

{

*parm = 5: /* Та же переменная, что и "global" */

return 6;

}

х = a[global] + f(&global);

В этом примере, если выражение вычисляется в том порядке, в котором оно записано, его значение равно а[4] + 6, но из-за совмещения имен значение выражения может быть 6 + а[5], если компилятор при вычислении выражения выберет порядок, при котором вызов функции предшествует индексации массива. Совмещение имен часто приводит к непереносимости программ.

Реальный недостаток «вызова по ссылке» состоит в том, что этот механизм по сути своей ненадежен. Предположим, что по некоторым причинам под­программа считает, что фактический параметр — массив, тогда как реально это всего лишь одно целое число. Это может привести к тому, что будет затер­та некоторая произвольная область памяти, так как подпрограмма работает с фактическим параметром, а не просто с локальной копией. Этот тип ошибки встречается очень часто, потому что подпрограмма обычно пишется не тем программистом, который разрабатывает вызывающую программу, и всегда возможно некоторое недопонимание.

Безопасность передачи параметров можно повысить с помощью строгого контроля соответствия типов, который гарантирует, что типы формальных и фактических параметров совместимы. Однако все еще остается возможность недопонимания между тем программистом, кто написал подпрограмму, и тем, чьи данные модифицируются. Таким образом, мы имеем превосходный механизм передачи параметров, который не всегда достаточно эффективен (семантика copy-in), а также необходимые, но ненадежные механизмы (семантика copy-out и семантика ссылки). Выбор усложняется ограничения­ми, которые накладывают на программиста различные языки программиро­вания. Теперь мы подробно опишем механизмы передачи параметров для не­скольких языков.

Параметры в языках С и C++

В языке С есть только один механизм передачи параметров — copy-in:

int i = 4; /* Глобальная переменная */

C

void proc(int i, float f)

{

i=i+(int) f; /* Локальная переменная "i" */

}

proc(j, 45.0); /* Вызов функции */

В ргос изменяемая переменная i является локальной копией, а не глобальной переменной i.

Чтобы получить функциональные возможности семантики ссылки или copy-out, пишущий на С программист должен прибегать к явному использо­ванию указателей:

int i = 4; /* Глобальная переменная */ [с]

void proc(int *i, float f)

{

*i = *i+ (int) f; /* Косвенный доступ */

}

proc(&i, 45.0); /* Понадобилась операция получения адреса */

После выполнения ргос значение глобальной переменной i изменится. Необходимость пользоваться указателями для реализации ссылочной семантики следует отнести к неудачным решениям в языке С, потому что на­чинающим программистам приходится изучать это относительно сложное понятие в начале курса.

В языке C++ этот недостаток устранен, поскольку в нем есть возможность задавать параметры специального ссылочного типа (reference parameters):

int i = 4; // Глобальная переменная

C++


void proc(int & i, float f)

{

i = i + (int) f; // Доступ по ссылке

}

proc(i, 45.0); // He нужна операция получения адреса

Обратите внимание на естественность стиля программирования, при ко­тором нет неестественного использования указателей. Это усовершенствова­ние механизма передачи параметров настолько важно, что оправдывает использование C++ в качестве замены С.

Вам часто придется применять указатели в С или ссылки в C++ для пере­дачи больших структур данных. Конечно, в отличие от копирования парамет­ров (copy-in), существует опасность случайного изменения фактического па­раметра. Можно задать для параметра доступ только для чтения, объявив его константой:

void proc(const Car_Data & d)

{

d.fuel = 25; // Ошибка, нельзя изменять константу

}

Объявления const следует использовать возможно шире, как для того, чтобы сделать смысл параметров более прозрачным для читателей программы, так и для того, чтобы отлавливать возможные ошибки.

Другая проблема, связанная с параметрами в языке С, состоит в том, что массивы не могут быть параметрами. Если нужно передать массив, передает­ся адрес первого элемента массива, а процедура отвечает за правильный до­ступ к массиву. Для удобства имя массива в качестве параметра автоматически рассматривается как указатель на первый элемент:

intb[50]; /* Переменная типа массив */

C

void proc(int a[ ]) /* "Параметр-массив" */

{

а[100] = а[200]; /* Сколько элементов? */

}

proc(&b[0]); /* Адрес первого элемента */

proc(b); /* Адрес первого элемента */

Программисты, пишущие на С, быстро к этому привыкают, но, все равно, это является источником недоразумений и ошибок. Проблема состоит в том, что, поскольку параметр — это, фактически, указатель на отдельный элемент, то допустим любой указатель на переменную того же типа:

int i;

void proc(int a[ ]); /* "Параметр-массив" */

proc(&i); /* Допустим любой указатель на целое число!! */

Наконец, в языке С контроль соответствия типов никак не действует между файлами, поэтому можно в одном файле поместить

C

[С] void proc(float f) { ...} /* Описание процедуры */

а в другом файле —

C

void proc(int i); /* Объявление процедуры */ ргос(100);

а затем месяцами искать ошибку.

Характеристики

Тип файла
Документ
Размер
2,54 Mb
Тип материала
Высшее учебное заведение

Список файлов книги

Свежие статьи
Популярно сейчас
Почему делать на заказ в разы дороже, чем купить готовую учебную работу на СтудИзбе? Наши учебные работы продаются каждый год, тогда как большинство заказов выполняются с нуля. Найдите подходящий учебный материал на СтудИзбе!
Ответы на популярные вопросы
Да! Наши авторы собирают и выкладывают те работы, которые сдаются в Вашем учебном заведении ежегодно и уже проверены преподавателями.
Да! У нас любой человек может выложить любую учебную работу и зарабатывать на её продажах! Но каждый учебный материал публикуется только после тщательной проверки администрацией.
Вернём деньги! А если быть более точными, то автору даётся немного времени на исправление, а если не исправит или выйдет время, то вернём деньги в полном объёме!
Да! На равне с готовыми студенческими работами у нас продаются услуги. Цены на услуги видны сразу, то есть Вам нужно только указать параметры и сразу можно оплачивать.
Отзывы студентов
Ставлю 10/10
Все нравится, очень удобный сайт, помогает в учебе. Кроме этого, можно заработать самому, выставляя готовые учебные материалы на продажу здесь. Рейтинги и отзывы на преподавателей очень помогают сориентироваться в начале нового семестра. Спасибо за такую функцию. Ставлю максимальную оценку.
Лучшая платформа для успешной сдачи сессии
Познакомился со СтудИзбой благодаря своему другу, очень нравится интерфейс, количество доступных файлов, цена, в общем, все прекрасно. Даже сам продаю какие-то свои работы.
Студизба ван лав ❤
Очень офигенный сайт для студентов. Много полезных учебных материалов. Пользуюсь студизбой с октября 2021 года. Серьёзных нареканий нет. Хотелось бы, что бы ввели подписочную модель и сделали материалы дешевле 300 рублей в рамках подписки бесплатными.
Отличный сайт
Лично меня всё устраивает - и покупка, и продажа; и цены, и возможность предпросмотра куска файла, и обилие бесплатных файлов (в подборках по авторам, читай, ВУЗам и факультетам). Есть определённые баги, но всё решаемо, да и администраторы реагируют в течение суток.
Маленький отзыв о большом помощнике!
Студизба спасает в те моменты, когда сроки горят, а работ накопилось достаточно. Довольно удобный сайт с простой навигацией и огромным количеством материалов.
Студ. Изба как крупнейший сборник работ для студентов
Тут дофига бывает всего полезного. Печально, что бывают предметы по которым даже одного бесплатного решения нет, но это скорее вопрос к студентам. В остальном всё здорово.
Спасательный островок
Если уже не успеваешь разобраться или застрял на каком-то задание поможет тебе быстро и недорого решить твою проблему.
Всё и так отлично
Всё очень удобно. Особенно круто, что есть система бонусов и можно выводить остатки денег. Очень много качественных бесплатных файлов.
Отзыв о системе "Студизба"
Отличная платформа для распространения работ, востребованных студентами. Хорошо налаженная и качественная работа сайта, огромная база заданий и аудитория.
Отличный помощник
Отличный сайт с кучей полезных файлов, позволяющий найти много методичек / учебников / отзывов о вузах и преподователях.
Отлично помогает студентам в любой момент для решения трудных и незамедлительных задач
Хотелось бы больше конкретной информации о преподавателях. А так в принципе хороший сайт, всегда им пользуюсь и ни разу не было желания прекратить. Хороший сайт для помощи студентам, удобный и приятный интерфейс. Из недостатков можно выделить только отсутствия небольшого количества файлов.
Спасибо за шикарный сайт
Великолепный сайт на котором студент за не большие деньги может найти помощь с дз, проектами курсовыми, лабораторными, а также узнать отзывы на преподавателей и бесплатно скачать пособия.
Популярные преподаватели
Добавляйте материалы
и зарабатывайте!
Продажи идут автоматически
6353
Авторов
на СтудИзбе
311
Средний доход
с одного платного файла
Обучение Подробнее