Kas yra uodegos skambutis?

Kompiuterių programavime uodegos iškvietimas yra konkreti situacija programos šaltinio kode, kai funkcija, paprogramė arba procedūra grąžina laukiamą reikšmę, iškviesdama kitą funkciją, o ne tiesiog perduodama kintamąjį, turintį grąžinamąją reikšmę. Pats pavadinimas reiškia, kad funkcija, iškviesta apskaičiuoti grąžintiną reikšmę, yra funkcijos, iškviečiančios ją pateikti grąžinamąją vertę, pabaigoje arba gale. Kai kuriuos programuotojus domina uodegos iškvietimas, nes esant tam tikram optimizavimui ar kompiliatoriaus elgsenai, pagrindinės funkcijos kodo vietoms saugoti nenaudojama papildomos dėklo vietos; Vietoj to uodegos funkcija naudojama grąžinamos vertės ataskaitoms generuoti tiesiai į iškvietimo tašką, kuriame buvo iškviesta pradinė funkcija. Uodeginio iškvietimo naudojimas yra ypač naudingas situacijose, kai naudojama rekursija, nes dėklo erdvė, naudojama skambintojų adresams saugoti, tais atvejais, kai rekursyvūs skambučiai yra labai giliai, gali greitai pasibaigti ir sustabdyti programos vykdymą. Nors tailiniai skambučiai gali padėti padidinti programos greitį, atminties naudojimą ir efektyvumą, tai taip pat gali sukelti situacijų, kai šaltinio kodas yra pertvarkytas, kad būtų galima naudoti skambučius taip, kad būtų sunku derinti ir sekti, ypač kai rekursija.

Iškvietimo uodegos egzistavimą daugiausia lemia tai, kaip skambučių krūva veikia daugumoje kompiuterių programų ir sistemos architektūrų. Krūvas, kuris yra tarsi plokščių krūva, yra duomenų struktūra „pirmas į jas ir paskutinė“. Kai iškviečiama funkcija, paprogramė arba procedūra, adresas, iš kurio skambinama, vadinamas dėklo rėmeliu, išsaugomas krūvoje. Tai reiškia, kad programa, kuri iškviečia funkciją A, kuri vėliau iškviečia funkciją B, turės du dėklo kadrus: vieną funkcijai B, o kitą – funkcijai A. Kai funkcija B bus baigta vykdyti, jos krūvos rėmelis iškeliamas iš viršaus. dėklas ir vykdymas grįžta į funkciją A, kurios rėmelis iššoko iš krūvos, kai tai atlikta, ir galiausiai grąžinamas programos valdymas į tašką, iš kurio buvo iškviesta pirmoji funkcija.

Kai naudojamas uodegos iškvietimas, funkcijos grąžinimo sakinys tiesiogiai naudoja kitos funkcijos grąžinimo reikšmę kaip duomenis, kurie turi būti siunčiami į iškvietimo kodą. Aukščiau pateiktame pavyzdyje funkcija A iškviečia funkciją B tiesiogiai su return sakiniu, tada buvo suformuotas uodegos iškvietimas. Iškvietimo grupėje, užuot turėjusi dėklo rėmelį abiem funkcijoms A ir B, funkcija B gaus grįžtamąjį adresą iš funkcijos A, o funkcijos A krūvos rėmelis bus iškeltas ir pašalintas, o tai reiškia, kad funkcija B perduos grąžinamąją vertę tiesiai atgal. į vietą, kuri iškvietė funkciją A, prieš tai neperduodant valdymo funkcijai A. Tai padidina funkcijų iškvietimų greitį ir padeda sumažinti informacijos kiekį krūvelėje.

Dėl uodegos skambučio savybių jie gali būti labai patrauklūs rekursinėms funkcijoms. Rekursyvinė funkcija yra ta, kuri pakartotinai išsikviečia, kad apskaičiuotų reikšmę, kaip gali būti einant sąrašo duomenų struktūra. Įdėtųjų funkcijų iškvietimams nekuriami jokie papildomi kamino rėmeliai, todėl labai gilus rekursijos lygis gali būti atliktas saugiai be tiesioginės dėklo perpildymo ir galimo programos nutraukimo grėsmės.