alt program - Subroutine

Olarak bilgisayar programlama , bir alt yordam bir dizisidir , program talimatları bir birim olarak paketlenmiş belirli bir görevi gerçekleştirir. Bu birim, daha sonra, söz konusu görevin gerçekleştirilmesi gereken her yerde programlarda kullanılabilir .

Altyordamlar, programlar içinde veya birçok program tarafından kullanılabilen kitaplıklarda ayrı ayrı tanımlanabilir . Farklı programlama dillerinde, bir alt program rutin , alt program , işlev , yöntem veya prosedür olarak adlandırılabilir . Teknik olarak, bu terimlerin hepsinin farklı tanımları vardır. Genel, şemsiye terim çağrılabilir birim bazen kullanılır.

Alt program adı , bir alt programın, daha büyük bir programda veya başka bir alt programda bir adım olarak kullanılan bir bilgisayar programıyla hemen hemen aynı şekilde davrandığını gösterir. Bir altyordam genellikle, programın bir yürütmesi sırasında, diğer altyordamlar da dahil olmak üzere, birkaç kez ve birkaç yerden başlatılabilmesi için kodlanır ve ardından , altyordamın görevi tamamlandıktan sonra, çağrıdan sonra bir sonraki talimata dallanır ( geri döner ). . Bir alt program fikri ilk olarak John Mauchly tarafından ENIAC üzerindeki çalışması sırasında tasarlandı ve Ocak 1947'de Harvard'da "EDVAC-tipi Makineler için Problemlerin Hazırlanması" konulu bir sempozyumda kaydedildi. Maurice Wilkes , David Wheeler ve Stanley Gill , genel olarak , açık bir alt program veya makronun aksine kapalı bir alt program olarak adlandırdıkları bu kavramın resmi icadıyla tanınırlar . Bununla birlikte, Turing , NPL ACE için tasarım önerileri üzerine 1945 tarihli bir makalesinde alt rutinleri tartışmıştı ve bir dönüş adresi yığını kavramını icat edecek kadar ileri gitmişti.

Altyordamlar güçlü bir programlama aracıdır ve birçok programlama dilinin sözdizimi , bunları yazmak ve kullanmak için destek içerir. Alt programların akıllıca kullanılması (örneğin, yapılandırılmış programlama yaklaşımı yoluyla ), genellikle büyük bir programın geliştirilmesi ve sürdürülmesinin maliyetini önemli ölçüde azaltırken, kalitesini ve güvenilirliğini artırır. Genellikle kütüphanelerde toplanan alt rutinler, yazılım paylaşımı ve ticareti için önemli bir mekanizmadır. Nesne yönelimli programlama disiplini, nesnelere ve yöntemlere (bunlar bu nesnelere veya nesne sınıflarına eklenmiş alt rutinlerdir) dayanmaktadır .

İş parçacığı kodu adı verilen derleme yönteminde , yürütülebilir program temel olarak bir dizi alt program çağrılarıdır.

Ana kavramlar

Bir alt yordamın içeriği, alt yordam çağrıldığında veya çağrıldığında yürütülen program kodunun parçası olan gövdesidir.

Çağıran programdan ( parametrelerini veya biçimsel parametrelerini değiştirmek için) bir veya daha fazla veri değeri elde etmeyi bekleyen bir alt program yazılabilir . Çağıran program, bu parametreler için argümanlar adı verilen gerçek değerleri sağlar . Farklı programlama dilleri, argümanları iletmek için farklı kurallar kullanabilir:

ortak düşünce Açıklama Genel kullanım
Değere göre çağrı Argüman değerlendirilir ve değerin kopyası alt programa iletilir Algol 60'tan sonra Pascal, Delphi, Simula, CPL, PL/M, Modula, Oberon, Ada ve diğerleri gibi çoğu Algol benzeri dilde varsayılan . C, C++, Java (Nesnelere ve dizilere yapılan referanslar da değere göre iletilir)
Referans ile arayın Bir argümana referans, tipik olarak adresi iletilir Algol 60'tan sonra Algol 68, Pascal, Delphi, Simula, CPL, PL/M, Modula, Oberon, Ada ve diğerleri gibi Algol benzeri dillerin çoğunda seçilebilir . C++, Fortran, PL/I
sonuca göre arama Parametre değeri, alt programdan geri döndüğünde argümana geri kopyalanır Ada OUT parametreleri
Değer-sonuca göre arama Parametre değeri, alt programa girişte ve geri dönüşte tekrar kopyalanır. Algol, Swift giriş-çıkış parametreleri
Ada göre ara Bir makro gibi – parametreleri değerlendirilmemiş argüman ifadeleriyle değiştirin Algol, Skala
Sabit değere göre arama Parametrenin sabit olarak ele alınması dışında değere göre çağırma gibi PL/I ATANMAZ parametreler, Ada IN parametreleri

Alt program, arayanına hesaplanmış bir değer döndürebilir ( dönüş değeri ) veya çeşitli sonuç değerleri veya çıktı parametreleri sağlayabilir. Aslında, altyordamların yaygın bir kullanımı, altyordamın amacının yalnızca değerleri tamamen altyordama iletilen argümanlar tarafından belirlenen bir veya daha fazla sonucu hesaplamak olduğu matematiksel işlevleri uygulamaktır . (Örnekler , bir sayının logaritmasını veya bir matrisin determinantını hesaplamayı içerebilir .) Bu türe fonksiyon denir.

Bir alt çağrı de sahip olabilir yan etkileri , örneğin modifiye olarak veri yapıları , bir de bilgisayar belleği , okuma ya da yazma çevresel aygıt , bir oluşturma dosyası , bir program ya da makinenin durdurulması, hatta belirli bir süre için programın yürütülmesine geciktirmek. Yan etkileri olan bir alt program, aynı argümanlarla çağrılsa bile, her çağrıldığında farklı sonuçlar döndürebilir. Bir örnek, birçok dilde mevcut olan ve her çağrıldığında farklı bir sözde rastgele sayı döndüren bir rastgele sayı alt yordamıdır . Yan etkileri olan alt programların yaygın kullanımı, zorunlu programlama dillerinin bir özelliğidir .

Bir altyordam , görevini yerine getirmek için bir veya daha fazla yerde kendini yinelemeli olarak çağırabilmesi için kodlanabilir . Bu yöntem, matematiksel tümevarım ve özyinelemeli böl ve yönet algoritmaları tarafından tanımlanan işlevlerin doğrudan uygulanmasına izin verir .

Amacı bir boolean değerli işlevi hesaplamak olan (yani bir evet/hayır sorusunu yanıtlamak) bir alt programa bazen yüklem denir. Gelen mantık programlama onlar öncelikle başarı veya başarısızlık belirlemek beri dillere, genellikle tüm alt fonksiyonlar, yüklemler'ıN denir.

Değer döndürmeyen veya boş değer döndüren bir alt programa bazen prosedür denir. Prosedürler genellikle argümanlarını değiştirir ve prosedürel programlamanın temel bir parçasıdır .

Dil desteği

Üst düzey programlama dilleri genellikle aşağıdakiler için özel yapılar içerir:

  • Alt programı oluşturan programın (gövde) bölümünü sınırlandırın
  • Alt programa bir tanımlayıcı (ad) atayın
  • Parametrelerinin adlarını ve veri türlerini ve dönüş değerlerini belirtin
  • Geçici değişkenleri için özel bir adlandırma kapsamı sağlayın
  • İçinde erişilebilir olan alt yordamın dışındaki değişkenleri tanımlayın
  • Alt programı çağır
  • Parametrelerine değerler sağlayın
  • Ana program, alt programın adresini içerir.
  • Alt program, ana programdaki fonksiyon çağrısının bir sonraki talimatının adresini içerir.
  • Gövdesinin içinden dönüş değerlerini belirtin
  • Çağıran programa dön
  • Bir çağrı tarafından döndürülen değerleri atın
  • Herhangi Kulp istisnai koşullar arama sırasında karşılaşılan
  • Alt programları bir modül , kitaplık , nesne veya sınıfa paketleyin

Bazı programlama dilleri gibi, Pascal , Fortran , Ada ve birçok lehçeler arasında BASIC , yapma işlevlerin veya fonksiyon alt programlar, çağıran programa açık bir dönüş değeri sağlamak ve subroutines veya prosedürler, ayırt. Bu dillerde, işlev çağrıları normalde ifadelere gömülür (örneğin, bir sqrtişlev olarak adlandırılabilir y = z + sqrt(x)). Prosedür ya kadar sözdizimsel davranırlar aramaları ifadeleri (örneğin bir printprosedür olarak adlandırılabilir if x > 0 then print(x)veya açıkça gibi bir ifade tarafından çağırılan CALLveya GOSUB(örneğin call print(x)). Gibi diğer diller, C ve Lisp , işlevleri ve değişmezler arasında ayrım yoktur.

Haskell gibi tamamen işlevsel programlama dillerinde , alt programların hiçbir yan etkisi olamaz , bu da programın çeşitli dahili durumlarının değişmeyeceği anlamına gelir. İşlevler, aynı argümanlarla tekrar tekrar çağrılırsa her zaman aynı sonucu döndürür. Bu tür diller tipik olarak yalnızca işlevleri destekler, çünkü bir değer döndürmeyen alt programların bir yan etkiye neden olmadıkça hiçbir faydası yoktur.

Gelen programlama dilleri gibi C , C ++ ve C # , altyordamlar da basitçe çağrılabilir fonksiyonları (ile karıştırılmamalıdır olmayabilir matematiksel fonksiyonlar ya da fonksiyonel programlama farklı kavramlardır).

Bir dilin derleyicisi genellikle prosedür çağrılarını çevirir ve iyi tanımlanmış bir çağrı kuralına göre makine talimatlarına geri döner , böylece alt rutinler onları çağıran programlardan ayrı olarak derlenebilir. Çağrı ve geri dönüş ifadelerine karşılık gelen talimat dizilerine prosedürün ön sözü ve son sözü denir .

Avantajlar

Bir programı alt programlara bölmenin avantajları şunları içerir:

  • Decomposing daha basit adımlara karmaşık bir programlama görevi: Bu iki ana araçlarından biridir yapısal programlama ile birlikte veri yapıları
  • Bir program içinde yinelenen kodun azaltılması
  • Birden çok programda kodun yeniden kullanımını etkinleştirme
  • Büyük bir programlama görevini çeşitli programcılar veya bir projenin çeşitli aşamaları arasında bölmek
  • Altyordamın kullanıcılarından uygulama ayrıntılarını gizleme
  • Tanımlayıcı bir işlev adının kod bloğunu tanımlamaya hizmet ettiği bir işlev çağrısıyla bir kod bloğunu değiştirerek kodun okunabilirliğini artırma . Bu, işlevin yeniden kullanılması amaçlanmasa bile, çağrı kodunu kısa ve öz ve okunabilir hale getirir.
  • İzlenebilirliğin iyileştirilmesi (yani çoğu dil, ilgili alt rutinlerin adlarını ve belki de dosya adları ve satır numaraları gibi daha fazla bilgiyi içeren çağrı izlemeyi elde etmenin yollarını sunar); kodu alt yordamlara ayırmayarak hata ayıklama ciddi şekilde bozulur

Dezavantajları

Hat içi kod kullanmaya kıyasla, bir alt yordamı çağırmak , çağrı mekanizmasında bir miktar hesaplama yükü getirir .

Bir alt program tipik olarak standart temizlik kodu gerektirir - hem işleve girişte hem de işlevden çıkışta ( işlev prologu ve sonsöz - genellikle genel amaçlı kayıtları ve dönüş adresini minimum olarak kaydeder ).

Tarih

Bir alt program fikri, bilgisayar makineleri bir süredir var olduktan sonra ortaya çıktı. Aritmetik ve koşullu atlama talimatları önceden planlandı ve nispeten az değişti, ancak prosedür çağrıları için kullanılan özel talimatlar yıllar içinde büyük ölçüde değişti. Manchester Baby ve RCA 1802 gibi en eski bilgisayarlar ve mikroişlemciler, tek bir alt rutin çağrı talimatına sahip değildi. Altyordamlar uygulanabilir, ancak programcıların her çağrı sitesinde çağrı dizisini (bir dizi talimat) kullanmasını gerektiriyordu .

Altyordamlar uygulanmıştır Konrad Zuse 'ın Z4 1945 yılında.

1945'te Alan M. Turing , "gömmek" ve "gömmek" terimlerini alt programlardan çağırma ve geri dönme aracı olarak kullandı.

Ocak 1947'de John Mauchly, Harvard Üniversitesi ve Birleşik Devletler Donanması Mühimmat Bürosu'nun ortak sponsorluğunda 'Büyük Ölçekli Dijital Hesaplama Makineleri Sempozyumu'nda genel notlar sundu. Burada seri ve paralel operasyon önermesini tartışıyor.

...makinenin yapısının biraz karmaşık olmasına gerek yok. Bu prosedür için gerekli tüm mantıksal özellikler mevcut olduğundan, alt rutinleri makine tarafından bilinen yerlere belleğe yerleştirmek için bir kodlama talimatını ve kolayca kullanıma çağrılabilecekleri şekilde geliştirmek mümkündür.

Başka bir deyişle, A alt rutini bölme olarak ve B alt rutini karmaşık çarpma olarak ve C alt rutini bir sayı dizisinin standart hatasının değerlendirilmesi olarak belirlenebilir ve bu şekilde belirli bir problem için gereken alt rutinler listesi aracılığıyla. ... Tüm bu alt programlar daha sonra makinede saklanacak ve tek yapılması gereken, kodlamada belirtildiği gibi, bunlara numara ile kısa bir referans vermek.

Kay McNulty , ENIAC ekibinde John Mauchly ile yakın bir şekilde çalışmış ve II. Dünya Savaşı sırasında programladığı ENIAC bilgisayarı için alt rutinler için bir fikir geliştirmişti . O ve diğer ENIAC programcıları, füze yörüngelerini hesaplamaya yardımcı olmak için alt rutinleri kullandılar.

Goldstine ve von Neumann , 16 Ağustos 1948'de alt programların kullanımını tartışan bir makale yazdılar.

IBM 1620 , Intel 4004 ve Intel 8008 ve PIC mikro denetleyicileri gibi çok eski bazı bilgisayarlar ve mikroişlemciler, dönüş adreslerini depolamak için ayrılmış bir donanım yığını kullanan tek komutlu bir alt yordam çağrısına sahiptir; bu tür donanımlar yalnızca birkaç düzeyi destekler. altyordam yuvalama, ancak özyinelemeli altyordamları destekleyebilir. 1960'ların ortalarından önceki makineler - UNIVAC I , PDP-1 ve IBM 1130 gibi - tipik olarak talimat sayacını çağrılan alt yordamın ilk bellek konumuna kaydeden bir çağrı kuralı kullanır . Bu, isteğe bağlı olarak derin alt yordam iç içe yerleştirme seviyelerine izin verir, ancak özyinelemeli alt yordamları desteklemez. PDP-11 (1970), bir yığın itme altprogram çağrısı komutu ile ilk bilgisayar biridir; bu özellik hem isteğe bağlı olarak derin alt yordam yerleştirmeyi destekler hem de özyinelemeli alt yordamları destekler.

Dil desteği

Çok erken montajcılarda, alt program desteği sınırlıydı. Alt rutinler, birbirlerinden veya ana programdan açıkça ayrılmamıştır ve aslında bir alt rutinin kaynak kodu, diğer alt programlarınkiyle serpiştirilebilir. Bazı derleyiciler , çağrı ve geri dönüş dizilerini oluşturmak için önceden tanımlanmış makrolar sunar. 1960'lara gelindiğinde, montajcılar genellikle birbirine bağlanabilen hem satır içi hem de ayrı olarak monte edilmiş alt rutinler için çok daha karmaşık desteğe sahipti.

Kullanıcı tarafından yazılan alt rutinleri ve işlevleri destekleyen ilk programlama dillerinden biri FORTRAN II idi . IBM FORTRAN II derleyicisi 1958'de piyasaya sürüldü. ALGOL 58 ve diğer erken programlama dilleri de yordamsal programlamayı destekledi.

Alt program kitaplıkları

Bu hantal yaklaşımla bile, alt programların çok faydalı olduğu kanıtlandı. Bir kere, aynı kodun birçok farklı programda kullanılmasına izin verdiler. Ayrıca, bellek ilk bilgisayarlarda çok kıt bir kaynaktı ve alt programlar programların boyutunda önemli tasarruflar sağlıyordu.

Birçok eski bilgisayar program talimatlarını delikli bir kağıt banttan belleğe yükledi . Her bir alt program daha sonra, ana programdan (veya "ana hat") önce veya sonra yüklenen veya birleştirilen ayrı bir bant parçası ile sağlanabilir; ve aynı alt program bandı daha sonra birçok farklı program tarafından kullanılabilir. Ana girişleri için delikli kartlar kullanan bilgisayarlarda da benzer bir yaklaşım uygulandı . Altyordam kitaplığı adı, orijinal anlamda, toplu kullanım için dizinlenmiş teyp veya kart destesi koleksiyonlarını tutan bir kitaplık anlamına geliyordu.

Dolaylı atlama ile dönüş

Kendi kendini değiştiren kod ihtiyacını ortadan kaldırmak için , bilgisayar tasarımcıları nihayetinde , işleneni dönüş adresinin kendisi olmak yerine, dönüş adresini içeren bir değişken veya işlemci kaydının konumu olan dolaylı bir atlama talimatı sağladı .

Bu bilgisayarlarda, altyordamın dönüş atlamasını değiştirmek yerine, çağıran program dönüş adresini bir değişkende saklar, böylece altyordam tamamlandığında, yürütmeyi önceden tanımlanmış değişken tarafından verilen konuma yönlendirecek dolaylı bir atlama gerçekleştirir.

Alt programa atla

Diğer bir ilerleme, dönüş adresinin kaydedilmesini çağıran atlama ile birleştiren, böylece ek yükü önemli ölçüde en aza indiren alt programa atlama talimatıydı .

Örneğin IBM System/360'ta , prosedür çağrısı için tasarlanmış BAL veya BALR şube talimatları, dönüş adresini, geleneksel kayıt 14 ile talimatta belirtilen bir işlemci kaydına kaydeder. bu kayıt aracılığıyla dolaylı bir dal talimatı (BR). Altyordam başka bir amaç için (başka bir altyordamı çağırmak gibi) bu kayda ihtiyaç duyuyorsa, yazmacın içeriğini özel bir bellek konumuna veya bir kayıt yığınına kaydeder .

HP 2100 gibi sistemlerde , JSB talimatı, dönüş adresinin şubenin hedefi olan bellek konumunda saklanması dışında benzer bir görevi yerine getirir. Prosedürün yürütülmesi aslında bir sonraki hafıza konumunda başlar. HP 2100 derleme dilinde, örneğin

       ...
       JSB MYSUB    (Calls subroutine MYSUB.)
 BB    ...          (Will return here after MYSUB is done.)

ana programdan MYSUB adlı bir alt programı çağırmak için. Alt program şu şekilde kodlanacaktır:

 MYSUB NOP          (Storage for MYSUB's return address.)
 AA    ...          (Start of MYSUB's body.)
       ...
       JMP MYSUB,I  (Returns to the calling program.)

JSB komutu, NEXT komutunun adresini (yani, BB) işleneni olarak belirtilen konuma (yani, MYSUB) yerleştirdi ve bundan sonra NEXT konumuna dallandı (yani, AA = MYSUB + 1). Alt program daha sonra MYSUB konumunda depolanan konuma dallanan JMP MYSUB, I dolaylı atlamasını yürüterek ana programa dönebilir.

Fortran ve diğer diller için derleyiciler, mevcut olduğunda bu talimatları kolayca kullanabilir. Bu yaklaşım, birden çok çağrı düzeyini destekledi; ancak bir alt rutinin dönüş adresi, parametreleri ve dönüş değerleri sabit bellek konumlarına atandığından, özyinelemeli çağrılara izin vermiyordu.

Bu arada, 1980'lerin başında Lotus 1-2-3 tarafından bir elektronik tabloda yeniden hesaplama bağımlılıklarını keşfetmek için benzer bir yöntem kullanıldı . Yani her hücrede iade adresini saklamak için bir yer ayrılmıştı . Yana dairesel referanslar doğal yeniden hesaplama sipariş için izin verilmez, bu çok gibi küçük bilgisayarlarda sınırlıydı bellekte bir yığın, için yer ayırmadan bir ağaç yürüyüşe izin veren IBM PC .

Çağrı yığını

Bir alt yordam çağrısının en modern uygulamaları, alt yordam çağrılarını ve dönüşlerini uygulamak için yığın veri yapısının özel bir durumu olan bir çağrı yığını kullanır . Her prosedür çağrısı, yığının tepesinde yığın çerçevesi adı verilen yeni bir giriş oluşturur ; prosedür döndüğünde, yığın çerçevesi yığından silinir ve alanı diğer prosedür çağrıları için kullanılabilir. Her yığın çerçevesi, tipik olarak prosedürün parametrelerini ve dahili değişkenleri ve dönüş adresini içeren ilgili çağrının özel verilerini içerir.

Çağrı dizisi, bir dizi sıradan komutla gerçekleştirilebilir (hâlâ azaltılmış komut seti hesaplaması (RISC) ve çok uzun komut kelimesi (VLIW) mimarilerinde kullanılan bir yaklaşım ), ancak 1960'ların sonlarından beri tasarlanan birçok geleneksel makine, özel komutlar içermiştir. bu amaç.

Çağrı yığını genellikle bitişik bir bellek alanı olarak uygulanır. Yığının alt kısmının bu alandaki en düşük veya en yüksek adres olması keyfi bir tasarım seçimidir, böylece yığın bellekte ileri veya geri büyüyebilir; ancak, birçok mimari ikincisini seçti.

Bazı tasarımlar, özellikle bazı Forth uygulamaları, biri esas olarak kontrol bilgileri (dönüş adresleri ve döngü sayaçları gibi) ve diğeri veri için olmak üzere iki ayrı yığın kullandı. İlki bir çağrı yığınıydı veya bir çağrı yığını gibi çalıştı ve programcı tarafından yalnızca diğer dil yapıları aracılığıyla dolaylı olarak erişilebilirken, ikincisi daha doğrudan erişilebilirdi.

Yığın tabanlı prosedür çağrıları ilk kez tanıtıldığında, değerli bellekten tasarruf etmek önemli bir motivasyondu. Bu şema ile derleyici, her prosedürün özel verileri (parametreler, dönüş adresi ve yerel değişkenler) için bellekte ayrı bir alan ayırmak zorunda değildir. Herhangi bir anda yığın, yalnızca o anda etkin olan aramaların (yani, aranan ancak henüz geri dönmeyen) özel verilerini içerir . Programların genellikle kitaplıklardan oluşturulma biçimleri nedeniyle, herhangi bir anda yalnızca bir avuç etkin olan binlerce alt yordam içeren programları bulmak nadir değildi (ve hala da öyle). Bu tür programlar için, çağrı yığını mekanizması önemli miktarda bellek tasarrufu sağlayabilir. Gerçekten de, çağrı yığını mekanizması, otomatik bellek yönetimi için en eski ve en basit yöntem olarak görülebilir .

Bununla birlikte, çağrı yığını yönteminin bir başka avantajı , aynı prosedüre yapılan her iç içe çağrı, kendi özel verilerinin ayrı bir örneğini aldığından, özyinelemeli alt program çağrılarına izin vermesidir .

Gecikmeli istifleme

Çağrı yığını mekanizmasının bir dezavantajı, bir prosedür çağrısının artan maliyeti ve buna karşılık gelen geri dönüşüdür. Ekstra maliyet, yığın işaretçisini artırmayı ve azaltmayı (ve bazı mimarilerde yığın taşmasını kontrol etmeyi) ve yerel değişkenlere ve parametrelere mutlak adresler yerine çerçeveye bağlı adreslerle erişmeyi içerir. Maliyet, artan yürütme süresi veya artan işlemci karmaşıklığı veya her ikisi ile gerçekleştirilebilir.

Bu ek yük en barizdir ve herhangi bir prosedür çağrısı yapmadan dönen yaprak prosedürlerinde veya yaprak işlevlerinde sakıncalıdır . Bu ek yükü azaltmak için, birçok modern derleyici, gerçekten ihtiyaç duyulana kadar bir çağrı yığınının kullanımını geciktirmeye çalışır. Örneğin, bir P prosedürünün çağrısı , çağrılan prosedürün dönüş adresini ve parametrelerini belirli işlemci kayıtlarında saklayabilir ve basit bir atlama ile kontrolü prosedürün gövdesine aktarabilir. P prosedürü başka bir çağrı yapmadan dönerse, çağrı yığını hiç kullanılmaz. Eğer P başka bir prosedür aramak gerekir Q , o zaman sonra gerekli olacaktır (örneğin dönüş adresi gibi) herhangi bir kayıt içeriğini kaydetmek için çağrı yığını kullanır S getiri.

C ve C++ örnekleri

In C ve C ++ programlama dilleri, alt programlar olarak adlandırılmaktadır fonksiyonları (ileri olarak sınıflandırılan üye fonksiyonları bir araya geldiklerinde sınıfın veya serbest fonksiyonlar değil). Bu diller void, bir işlevin herhangi bir değer döndürmediğini belirtmek için özel anahtar sözcüğü kullanır. C/C++ işlevlerinin, adresleri parametre olarak geçirilen değişkenleri değiştirmek de dahil olmak üzere yan etkileri olabileceğini unutmayın. Örnekler:

void Function1() { /* some code */ }

İşlev bir değer döndürmez ve bağımsız bir işlev olarak çağrılmalıdır, örn. Function1();

int Function2() {
  return 5;
}

Bu işlev bir sonuç döndürür (5 sayısı) ve çağrı bir ifadenin parçası olabilir, örn. x + Function2()

char Function3(int number) {
  char selection[] = {'S', 'M', 'T', 'W', 'T', 'F', 'S'};
  return selection[number];
}

Bu işlev, 0 ile 6 arasındaki bir sayıyı haftanın ilgili gününün ilk harfine, yani 0'dan 'S'ye, 1'den 'M'ye, ..., 6'dan 'S'ye dönüştürür. Onu çağırmanın sonucu bir değişkene atanabilir, örneğin num_day = Function3(number);.

void Function4(int* pointer_to_var) {
  (*pointer_to_var)++;
}

Bu işlev bir değer döndürmez, ancak adresi parametre olarak geçirilen değişkeni değiştirir; ile çağrılırdı Function4(&variable_to_increment);.

Küçük Temel örnek

Example()                               ' Calls the subroutine

Sub Example                             ' Begins the subroutine
    TextWindow.WriteLine("This is an example of a subroutine in Microsoft Small Basic.")  ' What the subroutine does
EndSub                                  ' Ends the subroutine

Yukarıdaki örnekte Example(), alt yordamı çağırır. Gerçek alt yordamı tanımlamak için Sub, alt yordam adından sonra gelen anahtar kelime kullanılmalıdır Sub. İçerik takip edildikten sonra EndSubyazılmalıdır.

Visual Basic 6 örnekleri

Gelen Visual Basic 6 dilde, alt programlar olarak adlandırılmaktadır işlevler veya subs (veya yöntemler bir sınıf ile ilişkili). Visual Basic 6, parametre olarak geçirilenleri tanımlamak için tür adı verilen çeşitli terimler kullanır . Varsayılan olarak, belirtilmemiş bir değişken bir varyant türü olarak kaydedilir ve ByRef (varsayılan) veya ByVal olarak geçirilebilir . Ayrıca, bir işlev veya alt bildirildiğinde, kendisine bildirildiği modül veya proje dışından erişilip erişilemeyeceğini belirleyen bir genel, özel veya arkadaş ataması verilir.

  • Değere göre [ByVal] – adresi iletmek yerine değerin bir kopyasını ileterek bir argümanın değerini bir prosedüre geçirmenin bir yolu. Sonuç olarak, değişkenin gerçek değeri, geçirildiği prosedürle değiştirilemez.
  • Referansla [ByRef] – değerinin bir kopyasını iletmek yerine değişkenin adresini ileterek bir argümanın değerini bir prosedüre geçirmenin bir yolu. Bu, prosedürün gerçek değişkene erişmesine izin verir. Sonuç olarak, değişkenin gerçek değeri, geçirildiği prosedürle değiştirilebilir. Aksi belirtilmedikçe, argümanlar referansla iletilir.
  • Genel (isteğe bağlı) – işlev prosedürüne tüm modüllerdeki diğer tüm prosedürlere erişilebilir olduğunu gösterir. Özel Seçenek içeren bir modülde kullanılırsa, prosedür proje dışında kullanılamaz.
  • Özel (isteğe bağlı) – işlev prosedürüne yalnızca bildirildiği modüldeki diğer prosedürler tarafından erişilebilir olduğunu gösterir.
  • Arkadaş (isteğe bağlı) – yalnızca bir sınıf modülünde kullanılır. İşlev prosedürünün proje boyunca görünür olduğunu, ancak bir nesne örneğinin denetleyicisi tarafından görülmediğini gösterir.
Private Function Function1()
    ' Some Code Here
End Function

İşlev bir değer döndürmez ve bağımsız bir işlev olarak çağrılmalıdır, örn. Function1

Private Function Function2() as Integer
    Function2 = 5
End Function

Bu işlev bir sonuç döndürür (5 sayısı) ve çağrı bir ifadenin parçası olabilir, örn. x + Function2()

Private Function Function3(ByVal intValue as Integer) as String
    Dim strArray(6) as String
    strArray = Array("M", "T", "W", "T", "F", "S", "S")
    Function3 = strArray(intValue)
End Function

Bu fonksiyon 0 ile 6 arasındaki bir sayıyı haftanın ilgili gününün ilk harfine, yani 0'dan 'M'ye, 1'den 'T'ye, ..., 6'dan 'S'ye dönüştürür. Onu çağırmanın sonucu bir değişkene atanabilir, örneğin num_day = Function3(number).

Private Function Function4(ByRef intValue as Integer)
    intValue = intValue + 1
End Function

Bu işlev bir değer döndürmez ancak adresi parametre olarak geçirilen değişkeni değiştirir; " Function4(variable_to_increment)" ile çağrılır .

PL/I örneği

Gelen PL / I olarak adlandırılan işlem, bir geçirilebilir tanımlayıcısı string uzunlukları ve dizi sınırlar olarak bağımsız değişken, hakkında bilgi sağlar. Bu, prosedürün daha genel olmasını sağlar ve programcının bu tür bilgileri iletme ihtiyacını ortadan kaldırır. Varsayılan olarak PL/I argümanları referansa göre iletir. İki boyutlu bir dizinin her bir elemanının işaretini değiştirmek için (önemsiz) bir alt program şöyle görünebilir:

  change_sign: procedure(array);
    declare array(*,*) float;
    array = -array;
    end change_sign;

Bu, aşağıdaki gibi çeşitli dizilerle çağrılabilir:

  /* first array bounds from -5 to +10 and 3 to 9 */
  declare array1 (-5:10, 3:9)float;
  /* second array bounds from 1 to 16 and 1 to 16 */
  declare array2 (16,16) float;
  call change_sign(array1);
  call change_sign(array2);

Python örneği

In Python , anahtar defbir işlev tanımlamak için kullanılır. Fonksiyonun gövdesini oluşturan ifadeler ya aynı satırda devam etmeli ya da bir sonraki satırda başlamalı ve girintili olmalıdır. Aşağıdaki örnek program "Merhaba dünya!" ardından bir sonraki satırda "Wikipedia" gelir.

def simple_function():
    print('Hello world!')
    print('Wikipedia')
simple_function()

Yerel değişkenler, özyineleme ve yeniden giriş

Bir alt program, belirli bir miktar karalama alanından yararlanmayı yararlı bulabilir ; yani, ara sonuçları tutmak için bu alt programın yürütülmesi sırasında kullanılan bellek . Bu karalama alanında depolanan değişkenler yerel değişkenler olarak adlandırılır ve karalama alanı bir etkinleştirme kaydı olarak adlandırılır . Bir etkinleştirme kaydının tipik olarak, alt program bittiğinde kontrolün nereye geri gönderileceğini söyleyen bir dönüş adresi vardır.

Bir alt program, herhangi bir sayıda ve nitelikte çağrı sitelerine sahip olabilir. Özyineleme destekleniyorsa, bir alt program kendisini çağırabilir ve aynı alt programın başka bir iç içe yürütmesi gerçekleşirken yürütmesinin askıya alınmasına neden olabilir . Özyineleme , bazı karmaşık algoritmaları basitleştirmek ve karmaşık sorunları çözmek için kullanışlı bir araçtır. Özyinelemeli diller genellikle her çağrıda yerel değişkenlerin yeni bir kopyasını sağlar. Programcı, çağrılar arasında yerel değişkenlerin değerinin aynı kalmasını isterse, bazı dillerde statik olarak bildirilebilir veya global değerler veya ortak alanlar kullanılabilir. Fibonacci sayılarını bulmak için C/C++'da özyinelemeli alt yordam örneği :

int Fib(int n) {
  if (n <= 1) {
    return n;
  }
  return Fib(n - 1) + Fib(n - 2);
}

Fortran gibi ilk diller başlangıçta özyinelemeyi desteklemedi çünkü değişkenler ve dönüş adresinin konumu statik olarak tahsis edildi. 1960'ların sonlarından önce PDP-8 gibi çoğu bilgisayarın donanım yığın kayıtları için desteği yoktu.

ALGOL'den sonraki PL/I ve C gibi modern diller neredeyse her zaman bir yığın kullanır, genellikle bir alt programın her yürütülmesi için yeni bir aktivasyon kaydı sağlamak için çoğu modern bilgisayar komut setleri tarafından desteklenir. Bu şekilde, iç içe geçmiş yürütme, devam etmekte olan diğer askıya alınmış yürütmeler üzerindeki etkiyle ilgilenmeden yerel değişkenlerini değiştirmekte özgürdür. İç içe çağrılar biriktikçe, askıya alınan her alt program için bir aktivasyon kaydından oluşan bir çağrı yığını yapısı oluşturulur. Aslında, bu yığın yapısı hemen hemen her yerde bulunur ve bu nedenle aktivasyon kayıtları yaygın olarak yığın çerçeveleri olarak adlandırılır .

Pascal , PL/I ve Ada gibi bazı diller , yalnızca bir dış (ana) alt yordam kapsamında çağrılabilen alt yordamlar olan iç içe alt yordamları da destekler . İç altyordamlar, kendilerini çağıran dış altyordamın yerel değişkenlerine erişime sahiptir. Bu, aktivasyon kaydı içinde ek bağlam bilgisinin depolanmasıyla gerçekleştirilir, buna ekran da denir .

Bir alt program, aynı alt programın başka bir yürütmesi halihazırda devam etmekteyken bile düzgün şekilde yürütülebiliyorsa, bu alt programın reentrant olduğu söylenir . Özyinelemeli bir alt program yeniden girişli olmalıdır. Yeniden girişli alt programlar, birden çok iş parçacığı , birbirine karışma korkusu olmadan aynı alt programı çağırabileceğinden, çok iş parçacıklı durumlarda da yararlıdır . In IBM CICS işlem sisteminin , yarı-evresel birçok iş parçacığı tarafından paylaşıldı uygulama programları için biraz daha az kısıtlayıcı, ancak benzer, gereklilik oldu.

Bir de , çok-dişli bir ortamda, genellikle birden fazla yığın vardır. Eşyordamları veya tembel değerlendirmeyi tam olarak destekleyen bir ortam, etkinleştirme kayıtlarını depolamak için yığınlar dışındaki veri yapılarını kullanabilir.

Aşırı yükleme

Kesin olarak yazılan dillerde , bazen aynı ada sahip, ancak farklı veri türleri üzerinde veya farklı parametre profilleri üzerinde çalışan birkaç işleve sahip olmak istenebilir. Örneğin, gerçekler, karmaşık değerler veya matrisler üzerinde çalışacak bir karekök işlevi tanımlanabilir. Her durumda kullanılacak algoritma farklıdır ve dönüş sonucu farklı olabilir. Programcı, aynı isimde üç ayrı fonksiyon yazarak, her bir veri tipi için farklı isimleri hatırlamak zorunda kalmamanın rahatlığını yaşar. Ayrıca, gerçekler için pozitif ve negatif gerçekleri ayırmak için bir alt tip tanımlanabiliyorsa, gerçekler için biri parametre pozitif olduğunda bir gerçek, diğeri parametre olduğunda karmaşık bir değer döndürmek için iki fonksiyon yazılabilir. olumsuz.

In nesne yönelimli programlama aynı adla fonksiyonları bir dizi farklı parametre profilleri veya farklı tiplerde parametrelerini kabul edebilir, fonksiyonların her söylenir aşırı .

İşte C++'da altyordam aşırı yüklemesine bir örnek :

#include <iostream>

double Area(double h, double w) { return h * w; }

double Area(double r) { return r * r * 3.14; }

int main() {
  double rectangle_area = Area(3, 4);
  double circle_area = Area(5);

  std::cout << "Area of a rectangle is " << rectangle_area << std::endl;
  std::cout << "Area of a circle is " << circle_area << std::endl;
}

Bu kodda aynı isimde iki fonksiyon vardır ancak bunların parametreleri farklıdır.

Başka bir örnek olarak, bir alt program , yönergeleri kabul edecek bir nesne oluşturabilir ve yolunu ekranda bu noktalara kadar izleyebilir. Yapıcıya iletilebilecek çok sayıda parametre vardır (izin rengi, başlangıç ​​x ve y koordinatları, izleme hızı). Programcı, yapıcının yalnızca renk parametresini kabul edebilmesini istiyorsa, yalnızca rengi kabul eden başka bir yapıcıyı çağırabilir ve bu da , diğer tüm parametreler için bir dizi varsayılan değerden geçen tüm parametrelerle birlikte yapıcıyı çağırır ( X ve Y genellikle ekranda ortalanır veya başlangıç ​​noktasına yerleştirilir ve hız, kodlayıcının seçtiği başka bir değere ayarlanır).

PL/I, GENERICfarklı argüman türleri ile çağrılan bir dizi girdi referansı için genel bir isim tanımlama özelliğine sahiptir . Örnek:

  DECLARE gen_name GENERIC(
                      name  WHEN(FIXED BINARY),
                      flame  WHEN(FLOAT),
                      pathname OTHERWISE 
                           );

Her giriş için birden fazla argüman tanımı belirtilebilir. "gen_name" çağrısı, argüman FIXED BINARY olduğunda "name" çağrısına, FLOAT olduğunda "flame", vb. ile sonuçlanır. Eğer argüman, seçeneklerin hiçbiri ile eşleşirse, "pathname" çağrılmayacaktır.

Kapanışlar

Bir kapatma , oluşturulduğu ortamdan yakalanan bazı değişkenlerinin değerleriyle birlikte bir alt programdır. Kapatmalar, John McCarthy tarafından tanıtılan Lisp programlama dilinin dikkate değer bir özelliğiydi . Uygulamaya bağlı olarak, kapatmalar yan etkiler için bir mekanizma işlevi görebilir.

Sözleşmeler

Alt rutinlerin kodlanması için çok sayıda sözleşme geliştirilmiştir. Adlandırmalarıyla ilgili olarak, birçok geliştirici, bir altyordamın adının, belirli bir görevi yerine getirdiğinde bir fiil , bazı sorgulamalar yaptığında sıfat ve değişkenleri değiştirmek için kullanıldığında bir isim olması gerektiği yaklaşımını benimsemiştir .

Bazı programcılar, bir alt rutinin yalnızca bir görevi gerçekleştirmesi gerektiğini ve bir alt rutinin birden fazla görevi gerçekleştirmesi durumunda, daha fazla alt rutine bölünmesi gerektiğini öne sürer. Alt programların kod bakımında anahtar bileşenler olduğunu ve programdaki rollerinin farklı kalması gerektiğini savunuyorlar .

Savunucuları modüler programlama (modüler hale kodu) savunucusu her altprogram kodun diğer parçalar üzerinde minimal bağımlılığı gerektiğini söyledi. Örneğin, genel değişkenlerin kullanımı, bu bakış açısının savunucuları tarafından genellikle akıllıca görülmemektedir, çünkü altyordam ve bu küresel değişkenler arasında sıkı bir bağlantı eklemektedir. Böyle bir bağlantı gerekli değilse, tavsiyeleri, bunun yerine geçilen parametreleri kabul etmek için alt rutinleri yeniden düzenlemektir . Ancak, alt programlara iletilen parametre sayısını artırmak, kodun okunabilirliğini etkileyebilir.

Dönüş kodları

Ana veya normal etkisinin yanı sıra , bir alt programın , yürütme sırasında meydana gelebilecek istisnai durumlar hakkında çağıran programı bilgilendirmesi gerekebilir. Bazı dillerde ve programlama standartlarında, bu genellikle , normal ve istisnai koşulları kodlayan bazı standart konumlarda alt program tarafından yerleştirilen bir tamsayı değeri olan bir dönüş kodu aracılığıyla yapılır .

Alt yordamdan dönüş kodunun beklendiği IBM System/360'ta , dönüş değeri genellikle 4'ün katı olacak şekilde tasarlanmıştır; böylece, genellikle hemen sonra yer alan bir dal tablosuna doğrudan dal tablosu dizini olarak kullanılabilir . Ekstra koşullu testlerden kaçınmak için talimatı çağırın ve verimliliği daha da artırın. In Sistemi / 360 Assembly dilinde , örneğin, daha yazarsınız:

           BAL  14, SUBRTN01    go to a subroutine, storing return address in R14
           B    TABLE(15)      use returned value in reg 15 to index the branch table, 
*                              branching to the appropriate branch instr.
TABLE      B    OK             return code =00   GOOD                  }
           B    BAD            return code =04   Invalid input         } Branch table
           B    ERROR          return code =08   Unexpected condition  }

Alt program çağrılarının optimizasyonu

Bir alt yordamın çağrılmasında, argümanların iletilmesi, alt programa dallanma ve arayana geri dallanma da dahil olmak üzere önemli bir çalışma zamanı ek yükü vardır. Genel gider genellikle belirli işlemci kayıtlarının kaydedilmesini ve geri yüklenmesini, çağrı çerçevesi depolamasının tahsis edilmesini ve geri alınmasını vb. içerir. Bazı dillerde, her bir alt program çağrısı aynı zamanda alt rutinin dönüş kodunun otomatik olarak test edilmesini veya ortaya çıkarabileceği istisnaların ele alınmasını da içerir . Nesne yönelimli dillerde önemli bir ek yük kaynağı, yöntem çağrıları için yoğun olarak kullanılan dinamik göndermedir .

Prosedürlerin yan etkileri olabilirse uygulanamayan, görünüşte bariz olan prosedür çağrıları optimizasyonları vardır. Örneğin, ifadede (f(x)-1)/(f(x)+1), fiki çağrı farklı sonuçlar döndürebileceğinden , işlev iki kez çağrılmalıdır. Ayrıca, xilk arama değiştirmiş olabileceğinden , değeri ikinci aramadan önce tekrar getirilmelidir. Bir alt programın yan etkisinin olup olmadığını belirlemek çok zordur (aslında Rice teoremi nedeniyle karar verilemez ). Bu nedenle, bu optimizasyonlar tamamen işlevsel programlama dillerinde güvenli olsa da, tipik zorunlu programlamanın derleyicileri genellikle en kötüsünü varsaymak zorundadır.

satır içi

Bu ek yükü ortadan kaldırmak için kullanılan bir yöntem , her bir çağrı sitesinde alt program gövdesinin satır içi genişletilmesi veya satır içine alınmasıdır (alt programa ve geriye dallanmaya karşı). Sadece çağrı havai Bunu önlemek yapar, ama aynı zamanda verir derleyicisi için optimize yordamın vücudunu hesaba konusu çağrı bağlamı ve argümanlar alarak daha etkili. Eklenen gövde derleyici tarafından optimize edilebilir. Ancak satır içi, program alt programa yalnızca bir çağrı içermedikçe, genellikle kod boyutunu artıracaktır.

popüler medyada Trope

"Alt program" terimi, 1990'lardan beri televizyon ve filmlerde sayısız kez kullanılmıştır. Bazen günümüzde, bazen de uzak bir gelecekte geçen, bilgisayar programlama veya hackleme içeren herhangi bir olay örgüsü unsuru bu kavramı çağrıştırabilir; çoğu zaman yanlış uygulanır.

Ayrıca bakınız

Referanslar