Dönüş ifadesi - Return statement

İçinde bilgisayar Programlama, bir dönüş ifadesi yürütmenin akımı terk etmesine neden olur altyordam ve alt yordam olarak bilinen talimatın hemen ardından koddaki noktadan devam edin. iade adresi. Dönüş adresi, arama rutini tarafından, bugün genellikle sürecin çağrı yığını veya içinde Kayıt ol. Birçok dildeki dönüş ifadeleri, bir işlevin bir geri dönüş değeri geri dönecek kodu buna işlev denir.

Genel Bakış

İçinde C ++, dönüş tecrübe; (nerede tecrübe bir ifade ) bir Beyan bu, bir işleve programın yürütülmesini çağıran işleve döndürmesini ve değerini bildirmesini söyler tecrübe. Bir işlevin dönüş türü varsa geçersiz, return ifadesi bir değer olmadan kullanılabilir, bu durumda program sadece mevcut fonksiyondan çıkar ve çağıran fonksiyona geri döner.

İçinde Pascal dönüş ifadesi yoktur. (Ancak, daha yeni Pascallarda, Çıkış(tecrübe); hemen bir değer döndürmek için kullanılabilir. Parametreler olmadan, sadece yordamı bozar.) Yürütme son çalıştırılabilir ifadesine ulaştığında bir alt yordam otomatik olarak geri döner. Değerler, alt yordamla aynı ada sahip bir tanımlayıcıya atanarak döndürülebilir. işlevi Pascal terminolojisinde. Bu şekilde işlev tanımlayıcısı, özyinelemeli çağrılar için ve sonuç sahibi olarak kullanılır; bu sözdizimsel olarak açık bir çıktı parametresi. Aynı sözdizimi, Fortran 66 ve Fortran 77 bir dönüş ifadesi eklenmesine rağmen FORTRAN II. Diğer bazı dillerde, işlev tanımlayıcı yerine kullanıcı tanımlı bir sonuç değişkeni kullanılır.

Oberon (Oberon-07 ) return ifadesi yerine bir return cümlesi vardır. İade maddesi, prosedür organının son ifadesinin arkasına yerleştirilir. Bu, prosedürden uygun dönüş ve dönüş değerinin derleme sırasında kontrol edilmesini sağlar.

Biraz ifade odaklı programlama dili, gibi Lisp, Perl ve Yakut, programcının açık bir dönüş ifadesini atlamasına izin verin, bunun yerine son değerlendirilen ifadenin alt rutinin dönüş değeri olduğunu belirtin.

Diğer durumlarda, açık bir dönüş ifadesi yoksa bir Boş değer döndürülür: Python, değer Yok return ifadesi atlandığında döndürülür, JavaScript'te ise değer Tanımsız Geri döndü.

İçinde Windows PowerShell yakalanmayan tüm değerlendirilmiş ifadeler (örneğin, bir değişkene atanmış, oyuncular -e geçersiz veya borulu -e $ null ) alt yordamdan bir dizideki öğeler olarak veya yalnızca bir nesnenin yakalanmamış olması durumunda tek bir nesne olarak döndürülür.

Perl'de, bir alt yordamın dönüş değeri veya değerleri, çağrıldığı bağlama bağlı olabilir. En temel ayrım bir skaler çağıran kodun bir değer beklediği bağlam, bir liste çağıran kodun bir değerler listesi beklediği bağlam ve bir geçersiz çağıran kodun herhangi bir dönüş değeri beklemediği bağlam. Bir alt rutin, içeriği kullanarak Wantarray işlevi. Skaler bağlamda tanımsız bir değer ve liste bağlamında boş bir liste döndürmek için argümansız özel bir dönüş sözdizimi kullanılır. Skaler bağlam ayrıca ikiye ayrılabilir: Boole, numara, dizi ve çeşitli referans bağlamlar. Ayrıca, bağlama duyarlı nesne bağlamsal bir dönüş dizisi kullanılarak döndürülebilir, tembel değerlendirme skaler değerler.

Birçok işletim sistemleri bir programın bir sonuç döndürmesine izin verin (normalden ayrı olarak çıktı ) süreci sona erdiğinde; bu değerlere dönüş kodları veya daha spesifik olarak çıkış durumları. Bu yolla aktarılabilecek bilgi miktarı oldukça sınırlıdır, pratikte genellikle başarı veya başarısızlık sinyaliyle sınırlıdır. Programın içinden bu geri dönüş genellikle çağrılarak elde edilir Çıkış (sistem çağrısı) (C de bile yaygındır, burada alternatif geri dönüş mekanizması ana işlev kullanılabilir).

Sözdizimi

İade ifadeleri birçok şekilde gelir. Aşağıdaki sözdizimleri en yaygın olanıdır:

Dilİade BeyanıDeğer atlanırsa Return
Ada, Bash,[1] C, C ++, Java, PHP, C #, JavaScript, D
dönüş değer;
Bash'de, işlevde yürütülen son komutun çıkış değeri

C[2] ve C ++,[3] tanımlanmamış davranış işlev değer döndürüyorsa

PHP'de[4] İadeler BOŞ

Javascript'te,[5] değeri verir Tanımsız

Java ve C # 'de, işlev değer döndürüyorsa izin verilmez

TEMEL
DÖNÜŞ
Lisp
(dönüş değer)
son ifade değeri
Perl, Yakut
dönüş @values;dönüş $ değer;dönüş;

veya bağlamsal bir dönüş dizisi

son ifade değeri
PL / I
dönüş (ifade); dönüş;
tanımlanmamış davranış prosedür bir değer döndürüyor olarak ilan edilirse
Python
dönüş değer
Yok
Smalltalk
^ değer
Tcl
dönüşdönüş $ değerdönüş -kod hatası "Hata mesajı"

veya seçeneklerin daha karmaşık bir kombinasyonu

son ifade değeri
Visual Basic .NET
Dönüş değer
Windows PowerShell
dönüş değer;
nesne
x86 montajı
ret
eax kaydının içeriği (kurallara göre)

Bazılarında montaj dilleri, örneğin MOS Teknolojisi 6502, anımsatıcı "RTS" (Alt Programdan Yeniden Dönüş) kullanılır.

Çoklu iade ifadeleri

Açık bir dönüş ifadesine sahip diller, aynı işlevde birden çok dönüş ifadesinin olasılığını yaratır, bunun iyi bir şey olup olmadığı tartışmalıdır.

Güçlü taraftarları yapısal programlama her işlevin tek bir girişi ve tek bir çıkışı (SESE) olduğundan emin olun. Bu nedenle tartışıldı[6] bir alt yordamın metinsel sonu haricinde açık return ifadesinin kullanımından kaçınılması gerektiği, "erken dönmek" için kullanıldığında, bunun için ortaya çıkan aynı tür sorunlardan muzdarip olabileceğini göz önünde bulundurarak GİT Beyan. Tersine, daha derin iç içe geçme, okunabilirliğe zarar verme gibi alternatif daha kıvrımlı kod olduğunda return ifadesinin kullanılmasının faydalı olduğu söylenebilir.

2004 ders kitabında, David Watt "tek girişli çoklu çıkış kontrol akışlarının genellikle arzu edildiğini" yazar. Tennent'in çerçeve kavramını kullanma sıralayıcı Watt, çağdaş programlama dillerinde bulunan kontrol akışı yapılarını tekdüze bir şekilde tanımlıyor ve çoklu çıkış kontrol akışları bağlamında neden bazı sıralayıcı türlerinin diğerlerine göre tercih edildiğini açıklamaya çalışıyor. Watt, kısıtlanmamış gotosların (atlama sıralayıcıları) kötü olduğunu yazar çünkü okuyucu, atlamanın hedefi olan gerçek etiketi veya adresi bulup inceleyene kadar, atlama hedefi bir programın okuyucusu için kendi kendini açıklayıcı değildir. Buna karşılık Watt, bir geri dönüş sıralayıcısının kavramsal amacının, hedefini incelemek zorunda kalmadan kendi bağlamından açık olduğunu savunur. Dahası, Watt olarak bilinen bir sıralayıcı sınıfının kaçış sıralayıcıları"Metinsel olarak çevreleyen bir komutun veya prosedürün yürütülmesini sonlandıran sıralayıcı" olarak tanımlanan, her ikisini de kapsar molalar döngülerden (çok seviyeli sonlar dahil) ve dönüş ifadeleri. Watt ayrıca, hedefin yerel bloğun içinde veya çevreleyen bir dış blok olması gereken C gibi dillerde atlama sıralayıcılarının (gotos) bir şekilde kısıtlanmış olmasına rağmen, bu kısıtlamanın tek başına gotos'un amacını C selfinde yapmak için yeterli olmadığını belirtmektedir. - tanımlıyor ve böylece üretebilsinler "spagetti kodu ". Watt ayrıca istisna sıralayıcıların kaçış ve atlama sıralayıcılardan nasıl farklı olduğunu da inceler; bununla ilgili ayrıntılar için şu makaleye bakın: yapısal programlama.[7]

Tarafından alıntılanan ampirik çalışmalara göre Eric S. Roberts, öğrenci programcılar bir dilde birkaç basit problem için doğru çözümleri formüle etmekte zorluk yaşadılar. Pascal, birden fazla çıkış noktasına izin vermez. Bir dizideki bir elemanı doğrusal olarak aramak için bir fonksiyon yazma problemi için, Henry Shapiro tarafından 1980 yılında yapılan bir çalışma (Roberts tarafından alıntılanmıştır), sadece Pascal tarafından sağlanan kontrol yapılarını kullanarak, doğru çözümün deneklerin yalnızca% 20'si tarafından verildiğini buldu. , hiçbir konu bir döngünün ortasından bir dönüş yazmasına izin verilirse bu sorun için yanlış kod yazmaz.[8]

Dahil diğerleri Kent Beck ve Martin Fowler bir veya daha fazla koruma hükümleri - bir işlevin başlangıcına yakın koşullu "erken çıkış" dönüş ifadeleri - genellikle bir işlevi alternatifinden daha kolay okunur hale getirir.[9][10][11][12]

Erken çıkıştaki en yaygın sorun, temizleme veya son ifadelerin yürütülmemesidir - örneğin, ayrılan belleğin ayrılmaması veya açık dosyaların kapatılmaması sızıntılara neden olur. Bunlar, kırılgan ve kolayca hatalara neden olabilecek her iade yerinde yapılmalıdır. Örneğin, sonraki geliştirmede, bir geliştirici tarafından bir dönüş ifadesi gözden kaçabilir ve bir alt yordamın sonunda gerçekleştirilmesi gereken bir eylem (örn. iz ifadesi) her durumda gerçekleştirilmeyebilir. Standart gibi dönüş ifadesi olmayan diller Pascal bu problem yok. C ++ ve Python gibi bazı diller, geri dönüşte (veya istisna atıldığında) eylemlerin otomatik olarak gerçekleştirilmesine izin veren ve bu sorunlardan bazılarını hafifleten kavramlar kullanır - bunlar genellikle "dene / son olarak" veya benzeri olarak bilinir. Bu "nihayet" cümleleri gibi işlevsellik, alt yordamın tek dönüş noktasına bir goto ile uygulanabilir. Alternatif bir çözüm, yerel değişkenler üzerindeki yıkıcılar veya Python'un "with" ifadesi gibi benzer mekanizmalar aracılığıyla kaynakları ayırmak için fonksiyon çıkışında normal yığın çözmeyi (değişken serbest bırakma) kullanmaktır.

Orijinal Pascal ve C gibi bazı erken dil uygulamaları, bir işlev tarafından döndürülebilen türleri kısıtladı (ör. kayıt veya yapı türleri) basitleştirmek için derleyiciler.

İçinde Java —Ve ondan sonra modellenen benzer diller, örneğin JavaScript - return ifadesinden sonra bile kod çalıştırmak mümkündür, çünkü en sonunda bir blok deneme-yakalama yapısı her zaman yürütülür. Öyleyse dönüş ifade içinde bir yere yerleştirilir Deneyin veya tutmak içindeki kodu engeller en sonunda (eklenirse) yürütülecektir. İlkel olmayan bir türün dönüş değerini (önceden döndürülmüş bir nesnenin özelliği) değiştirmek bile mümkündür, çünkü çıkış daha sonra da gerçekleşir.[13]

Getiri ifadeleri

İfadeleri döndürmek için kuzen getiri tabloları: bir dönüşün altrutin bitirmek, verim, rutin -e askıya alın. Koroutin daha sonra tekrar çağrılırsa askıya alındığı yerden devam eder. Coroutines, alt yordamlardan çok daha fazla uygulamaya yöneliktir ve bu nedenle, verim ifadeleri, dönüş ifadelerinden daha az yaygındır, ancak birkaç dilde bulunurlar.

Çağrı / dönüş dizileri

Aşağıdakiler dahil olmak üzere, donanım komut setine bağlı olarak bir dizi olası çağrı / dönüş dizisi mümkündür:

  1. TELEFON ETMEK talimat, adresini iter Sonraki Yığın ve dallarla ilgili talimatları belirtilen adrese. DÖNÜŞ komut, dönüş adresini yığından komut işaretçisine açar ve yürütme bu adreste devam eder. (Örnekler x86, PDP-11)
  2. TELEFON ETMEK talimat yerleri adresi Sonraki bir sicildeki talimat ve belirtilen adrese şubeler. DÖNÜŞ komut dizisi, dönüş adresini kayıttan komut işaretçisine yerleştirir ve yürütme bu adreste devam eder. (Örnek IBM System / 360)
  3. TELEFON ETMEK talimat yerleri adresi Sonraki (veya akım) çağrı adresindeki depolama konumunda talimat ve belirtilen adres + 1'e şubeler. DÖNÜŞ yönerge dizisi, dönüş adresine bir dolaylı alt programın ilk talimatına atlayın. (Örnekler IBM 1130, SDS9XX)

Ayrıca bakınız

Referanslar

  1. ^ Bash'de yalnızca 0-255 aralığındaki tam sayılar döndürülebilir: http://tldp.org/LDP/abs/html/complexfunct.html#RETURNREF
  2. ^ https://msdn.microsoft.com/en-us/library/sta56yeb.aspx MSDN: iade Bildirimi (C)
  3. ^ https://msdn.microsoft.com/en-us/library/k68ktdwf.aspx MSDN: return İfadesi (C ++)
  4. ^ "PHP: return - Manual". PHP Kılavuzu. PHP Grubu. Alındı 26 Mart 2013.
  5. ^ "İade - Javascript". MDN Javascript Referansı. Mozilla Geliştirici Ağı. Alındı 27 Mart 2013.
  6. ^ C ++ Notları: İşlev dönüş İfadesi
  7. ^ David Anthony Watt; William Findlay (2004). Programlama dili tasarım kavramları. John Wiley & Sons. s. 215–221. ISBN  978-0-470-85320-7.
  8. ^ Roberts, E. [1995] “Döngü Çıkışları ve Yapılandırılmış Programlama: Tartışmayı Yeniden Açmak,” ACM SIGCSE Bülteni, (27) 1: 268–272.
  9. ^ Martin Fowler, Kent Beck, John Brant, William Opdyke, Don Roberts."Yeniden Düzenleme: Mevcut Kodun Tasarımını İyileştirme (Google e-Kitap)".section "İç İçe Koşullu Koşulları Koruma Cümleleriyle Değiştirin" .2012.p. 237, p. 250.quote: "... bir çıkış noktası zihniyeti ... Bir yöntemden bir çıkış noktasıyla ilgili kurala uymuyorum."
  10. ^ Kent Beck."Uygulama Modelleri".2007. "Bölüm 7: Davranış", "Koruma İfadesi" bölümü.
  11. ^ "Çoklu iade ifadeleri"
  12. ^ Fred Swartz."Dönüş ifadeleri ve tek çıkış fantezisi".
  13. ^ Nihayet Engelleme, Java Öğreticileri