Özyinelemeli işlev çağrısında dönüş ifadesinin nedeni


14

Aklımda sadece bir şüphe vardı. Aşağıdaki alt yordamın (örneğin, bir listedeki bir öğeyi aramak için) sonunda bir döndürme ifadesi vardır:

list *search_list(list *l, item_type x) {
  if (l == NULL) return(NULL);
  if (l->item == x)
    return(l);
  else
    return( search_list(l->next, x) );
}

Sonunda dönüş deyiminin önemini alamıyorum (yani arama_listesi (l-> sonraki, x)). Yığın modelini kullanarak herhangi birinin bu kavramı açıklayabilmesi gerçekten yararlı olacaktır.


Listenin ilk terimi sonuç değilse , listenin geri kalanında arama yapın . Sonuncusu returnbunu yapar.
Giorgio

@ Giorgio, Neden sadece bir işlev çağrısı yeterli olmazdı, bundan önce neden geri dönüş gerekiyor?
user1369975

7
Çünkü fonksiyon tarafından döndürülen değeri döndürmeniz gerekiyor
Esailija

7
Downvoters: Lütfen OP'nin arka planına bağlı olarak, ne işe yaradığının açık olmadığını unutmayın return. Aslında, işlevsel dillerde (ve Scala gibi bazı karışık diller) return gerekli değildir : özyinelemeli işlevin değeri, son ifadesinin değeridir. Basitçe yazılı search_list(l->next, x)olmadan returnScala çalışmış olurdu! İfadenin anlamı returnsadece zorunlu bir arka plana sahip programcılar için açıktır.
Andres F.

OP: Kod pasajınız C ile yazılmış mı?
Andres F.17

Yanıtlar:


19

Bir return ifadesi , geçerli işlevin çağrı çerçevesinin hemen arayanına bir değer iletir. Özyineleme durumunda, bu anında arayan aynı işlevin başka bir çağrılması olabilir.

Çoğu dilde, aradığınız bir işlevin dönüş değerini (özyinelemeli olarak veya kullanmıyorsanız) kullanmazsanız, bu dönüş değeri atılır veya tanılanabilir bir hatadır. Son işlev çağrısının dönüş değerinin, geçerli işlev çağrısının dönüş değeri olarak otomatik olarak yeniden kullanıldığı bazı diller vardır, ancak normal ve özyinelemeli işlev çağrıları arasında ayrım yapmazlar.

Kodu şu şekilde yazdıysanız, kullanılmayan dönüş değerlerinin sessizce atıldığını varsayarsak:

list *search_list(list *l, item_type x) {
  if (l == NULL) return(NULL);
  if (l->item == x)
    return(l);
  else
    search_list(l->next, x); // no return!
}

Sonra search_listsadece boş bir listeye (NULL) için tanımlanmış bir değer döndürmek veya ediyorum ilk öğe aradığınız değeri eşleşirse. İşlev özyinelemeli çağrıya girer girmez sonucun ne olacağını bilmezsiniz, çünkü özyinelemeli çağrının sonucu atılır.

Ayrıca, işlevinizden bir değer döndürme sözü verirsiniz, ancak hangi değeri döndüreceğinizi belirtmediğiniz bir yolunuz (özyinelemeli olan) vardır. Kullandığınız dile bağlı olarak, bu genellikle zorunlu bir tanılama veya tanımlanmamış bir davranışla sonuçlanır (kısaca şudur: herhangi bir şey olabilir ve herhangi bir zamanda haber verilmeksizin değişebilir. en önemli sunumunuz). Eksik dönüş değerinin işe yaradığı görülebilecek bazı durumlar vardır, ancak programı bir sonraki çalıştırışınızda değişebilir (yeniden derleme olsun veya olmasın).


FWIW, Perl ki ben, otomatik son ifadenin sonucunu döndürür düşünüyorum o dönüş değeri yeniden kullanıyorlardı anlamına gelir. Ama yıllara dokunmadım, bundan emin değilim.
Bobson

1

İki şey; Aradığınız "x" karakterini bulmanız durumunda tüm listeyi döndürmek özyineleme kullanmak zorunda değildir, ancak bunu bir kenara bırakın:

X = "Aralık" değerini aradığınızı ve listenizin yılın aylarının sayısal değeri olduğunu, bir sonraki aya bir işaretçi olduğunu ve listedeki l-> öğelerinin, aydır. (Ocak, Şubat, ..., Aralık). Olası sonuçlar için üç geri dönüşe ihtiyacınız vardır. Liste, aradığınız X'i içermiyorsa, ilk dönüş (NULL) gerekir. İkincisi, (return (l)) listeyi döndürür, bu durumda "x" öğenizi bulduğunuzu bildirir. Sonuncusu, yığın modelinin devreye girdiği yerdir. Bu işleve yapılan ardışık çağrılar, yerel değişkenleri (özellikle, l-> item'in) şu şekilde güncelleyecektir:

1: l->item = January
   returns search_list(l->next, x)
2: l->item = February
   returns search_list(l->next, x)
3-11: March, April, May, June, July, August, September, October, November
   all return search_list(l->next, x)
12: l->item = December
  This matches the second if() and returns your list, letting you know you found your search item.

, illüstrasyonunuz için teşekkürler, ancak gerçekten son dönüşü kullanmayın
user1369975

Son dönüş olmadan, asla 1. adımı
geçemezsiniz
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.