Подпрограма: Разлика между версии

Изтрито е съдържание Добавено е съдържание
м Bot: Automated text replacement (-„([а-яА-Я0-9,\.\–\-\s]*?)\” +„\1“)
мРедакция без резюме
Ред 85:
 
=== Връщане чрез индиректно прехвърляне ===
За да се премахне нуждата от самомодифициращия се код, разработчиците са включили ''[[indirect branch|indirect jump]]'' инструкция, чиито операнд, вместо самия той да бъде [[адреса за връщане]], е съхранявал местоположението на променлива или [[Регистър (компютър)|регистър]] съдържащ в себе си адресът за връщане.
 
На тези компютри вместо да се модифицира връщането на контрола от подпрограмата, извикващата програма съхранява адресът за връщане в променлива, така че когато завърши изпълнението на подпрограмата, тя ще изпълни индиректно прехвърляне, което ще насочи изпълнението към позицията посочена от дефинираната вече променлива.
Ред 126:
Една от отрицателните страни на механизмът със стек е увеличената цена на извикването на подпрограма и съответстващото връщане. Допълнителният разход включва увеличаване и намаляване на пойнтера на стека (и в някои архитектури, проверка за [[препълване на стека]]), и достъпването на локалните променливи и параметри чрез frame-relative адреси, вместо чрез абсолютни адреси. Този недостатък може да се отрази чрез по-дълго време за изпълнение на програмата, или увеличено натоварване на процесора, или и двете.
 
Посоченият недостатъък е най-лесно видим и неприятен при ''leaf procedures'' or ''leaf functions'', които връщат контрола без да прявят извиквания на подпрограми.<ref>[http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/ka13785.html infocenter.arm.com]</ref><ref>[http://msdn.microsoft.com/en-gb/library/ms235286.aspx msdn.microsoft.com]</ref><ref>[http://msdn.microsoft.com/en-us/library/67fa79wz%28v=VS.90%29.aspx msdn.microsoft.com]</ref> Например, извикването на процедура „P“ може да съхранява адресът за връщане и параметрите на извиканата процедура в определени процесорни регистри и да прехвърли контрола към тялото на процедурата чрез обикновен скок. Ако процедурата „P“ трябва да извика нова процедура „Q“, тогава ще използва кол стека за да запази съдържанието на регистрите (като например адресът за връщане), което ще бъде необходимо след като „Q“ върне контрола.
 
== C и C++ примери ==
В езиците [[C (programming language)|C]] and [[C++]], подпрограмите са наименовани „функции“ (or ''member functions'' when associated with a [[class (computer programming)|class]]). Тези езици използват специален код <code>void</code> за да обозначат, че функцията не приема параметри (особено в С) и/или не връща стойност. Обърнете внимание, че C/C++ функциите могат да имат странични ефекти, включващи модификацията на променливи, чиито адреси са предадени като параметри (passed by reference). Примери:
<syntaxhighlight lang="c">
void function1(void) { /* some code */ }
</syntaxhighlight>
 
Функцията не връща стойност и трябва да бъде извикана като самостоятелна, например,
<code>function1();</code>
 
Ред 162:
</syntaxhighlight>
 
Тази функция не връща стойност, а модифицира промеливатапроменливата, чиито адрес е предаден като параметър; би била извикана с „<code>function4(&variable_to_increment);</code>“.
 
== Примери на Visual Basic 6 ==
При езика [[Visual Basic]] 6, подпрограмите са наречени функции или ''subs'' (или методи когато са асоциирани с даден клас). Visual Basic 6 използва различни terms наречени „types“ за да дефинира какво се предава като параметър. По подразбиране, unspecified variable се регистрира като [[variant type]] и може да бъде passed като ''ByRef'' (default) или ''ByVal''. Също така, когато функция или „sub“ е декларирана и се назначава public, private, or friend designation, което определя дали може да бъде достъпвана извън модула и/или проекта, в който е била декларирана.
* '''By value [ByVal]''' – начин за предаване на стойност на аргумент към процедура, вместо предаване на адреса. Това позволява процедурата да достъпва копие на променливата. РузълтатътРезултатът е, че реалната стойност на променливата не може да бъде променена от процедурата към която е предадена.
* '''By reference [ByRef]''' – начин за предаване на адрес на аргумент към процедура, вместо да се подава стойността. Това позволява на функцията да достъпва самата променлива, което означава, че реалната стойност може да бъде променяна от функцията на която е подадена. Ако не е посочено друго, аргументите се подават по референция.
* '''Public''' (optional) – показва че функцията е достъпна за всички останали във всички модули. Ако бъде използвана в модул Private, функцията няма да е достъпна извън този проект.
Ред 302:
 
=== Вграждане ===
Метод, използван, за да елиминира допълнителното време при изпълнението на програма, е ''вграждането'' на тялото на подпрограмата във всяко място на повикване (срещу разклоняването до подпрограмата и обратно). Това не само намалява времето за изпълнение, но и позволява на компилатора да оптимизира тялото на процедурата по-ефективно, като се вземат предвид контекста и аргументите в повикването. Вграждането обаче обикновено ще увеличи размера код, освен ако програмата не съдържа само едно повикване към подпрограмата или тялото на подпрограмата е по-малко като код от повикването.
 
== Бележки ==