Более простой ответ, чем (очень хороший) другой.
работает ли он так же, как в C, и процедура получает указатель на переменную и использует этот указатель.
Да, это то, что происходит под капотом.Процедура действительно получает указатель, адрес, к переменной.Но компилятор, зная это, делает его прозрачным.Таким образом, внутри процедуры, которая объявляет параметр «a», оператор:
a := a div 2;
может быть скомпилирован двумя различными способами.Если параметр a
объявлен нормально, т.е. передан по значению, оператор компилируется следующим образом:
1 - загрузить значение по адресу "a"
2 - целочисленное деление на два
3- сохранить результат по адресу "a"
Если вместо этого параметр был объявлен как var
, то есть передан по ссылке, компилятор делает:
1 - загрузить значение по адресу"a"
2 - загрузить значение по только что загруженному адресу (это разыменование указателя)
3 - делить
4 - вернуть обратно
Выше четыре оператораэто именно то, что компилирует C, если источник:
*a = *a / 2;
Наверное, я мог бы сформулировать свой вопрос так: Поддерживает ли Паскаль истинную передачу по ссылке ...?
Ответ - абсолютно да, это правда, передача по ссылке, и не многие языки делают это так хорошо и чисто.Исходный код для вызова процедуры не изменяется, независимо от того, вызывается ли процедура с помощью «по ссылке» или «по значению».Опять же, компилятор, зная, как должны передаваться формальные параметры, скрывает детали, в отличие от C. Например, вызовите процедуру, которая хочет, чтобы параметр передавался по значению:
myproc(a); // pascal and C are identical
Все становится иначеесли процедура ожидает передачи по ссылке:
myproc(a); // pascal: identical to before
myproc(&a); // C: the language does not hide anything
Об этом последнем пункте кто-то думает, что C лучше, потому что это заставляет программиста знать, что переданная переменная может быть изменена процедурой (функцией).Вместо этого я думаю, что паскаль более элегантен, и что программист все равно должен знать, что будет делать процедура.
Все это для «простых» типов.Если мы говорим о строках (а у современного паскаля есть две разновидности), то же самое - в Паскале.Компилятор копирует, увеличивает количество ссылок и делает все необходимое для полной поддержки передачи по значению или по ссылке.В языке C нет ничего похожего.
Если говорить о классах, то все по-другому, но они должны все равно различаться из-за семантики классов.
Надеюсьдобавить что-то к другому полному ответу.