Bu program her Tamsayı için sona erecek mi?


14

GATE Hazırlığı için Parça Testinde bir soru vardı:

f(n):
     if n is even: f(n) = n/2
     else f(n) = f(f(n-1))

"Tüm tamsayılar için sonlanacak" yanıtını verdim, çünkü bazı negatif tamsayılar için bile Yığın Taşma Hatası olarak sonlanacak .

Ancak arkadaşım, bu kod ve sadece sahte kod uygulanmadığından, bazı negatif tamsayılarda sonsuz özyineleme olacağını söyledi.

Hangi cevap doğrudur ve neden?


8
N = -1 için sonlandırılmaz. Bu gibi durumlarda çoğunlukla teorik sınırlar göz önünde bulundurulur.
Derin Joshi

9
Yığın taşması sonlandırma olarak değerlendirilecekse, tüm programlar sonlandırılır ve bu sorunun amacını yener ...
xuq01

10
@ xuq01 while (true);sona ermeyecek ve mantıklı bir şey üzerinde yığın taşmasına neden olmayacaktır.
TripeHound

3
@leftaroundabout Muhtemelen " mantıklı bir şeyde " kullanmamalıydım çünkü tamamen farklı bir " mantıklı " seviyedir ... kuyruk özyinelemeyi tespit etmek ve uygulamak güzeldir (hatta mantıklı ), ama bunu yapmamak sadece biraz " mantıklı değil ". Herhangi bir yığını while(true);kullanan bir şekilde uygulanan herhangi bir şey kesinlikle mantıklı olmaz . Mesele şu ki, kasıtlı olarak garip olmak için yola çıkmazsanız, while(true);yığın taşmasını sonlandırmaz veya tetiklemez.
TripeHound

14
@ xuq01 "Evrenin yok edilmesi" nin durma problemine bir çözüm olduğunu düşünmüyorum.
TripeHound

Yanıtlar:


49

Doğru cevap, bu fonksiyonun tüm tamsayılar için sonlandırılmamasıdır (özellikle -1'de sonlanmaz). Arkadaşınız bunun sahte kod olduğunu ve sahte kodun yığın taşmasıyla sonlanmadığını belirtmekte haklıdır. Sahte kod resmi olarak tanımlanmamıştır, ancak fikir teneke üzerinde söylenenleri yapmasıdır. Kod "yığın taşması hatasıyla sonlandır" demezse yığın taşması hatası olmaz.

Bu gerçek bir programlama dili olsa bile, yığının kullanımı dil tanımının bir parçası olmadığı sürece, doğru cevap yine de "sonlanmaz" olacaktır. Çoğu dil, yığının taşmasına neden olabilecek programların davranışını belirtmez, çünkü bir programın ne kadar yığının kullanılacağını tam olarak bilmek zordur.

Kodu gerçek bir yorumlayıcı veya derleyici üzerinde çalıştırmak, birçok dilde yığın taşmasına neden oluyorsa, bu, dilin biçimsel anlamıyla uygulama arasında bir tutarsızlıktır. Genelde, bir dil uygulamasının yalnızca sınırlı belleğe sahip beton bir bilgisayarda yapılabilecekleri yaptığı anlaşılmaktadır. Program yığın taşmasıyla ölürse, daha büyük bir bilgisayar satın almanız, gerekirse tüm bu belleği desteklemek için sistemi yeniden derlemeniz ve tekrar denemeniz gerekir. Program sonlandırılmıyorsa, bunu sonsuza kadar yapmaya devam etmeniz gerekebilir.

Kuyruk çağrısı optimizasyonu ve notlama gibi bazı optimizasyonlar , sabit bağlı yığın alanında sonsuz sayıda işlev çağrısı zincirine izin verebileceğinden , bir programın yığının taşmasına veya taşmamasına rağmen iyi tanımlanmamıştır . Bazı dil belirtimleri, uygulamaların mümkün olduğunda kuyruk çağrısı optimizasyonu yapmasını zorunlu kılar (bu fonksiyonel programlama dillerinde yaygındır). Bu işlev f(-1)için f(f(-2)); dış çağrı fbir kuyruk çağrısıdır, böylece yığının üzerinde hiçbir şey itmez, bu nedenle sadece f(-2)yığına gider ve bu geri döner -1, böylece yığın başlangıçta olduğu duruma geri döner . Böylece kuyruk çağrı optimizasyonu f(-1)ile sürekli bellekte sonsuza kadar döngüler.


3
Bir programlama diline çevrilen kodun yığın taşmasına neden olmadığı bir örnek Haskell'dir. Sadece süresiz olarak döngüler:let f :: Int -> Int; f n = if even n then n `div` 2 else f (f (n - 1)) in f (-1)
JoL

5

Buna C dili açısından bakarsak, bir uygulama, orijinalin tanımlanmamış davranışı çağırmadığı tüm durumlarda aynı sonucu üreten kodla kodu değiştirmekte özgürdür. Böylece yerini alabilir

f(n):
   if n is even: f(n) = n/2
   else f(n) = f(f(n-1))

ile

f(n):
   if n is even: f(n) = n/2
   else f(n) = f((n-1) / 2)

Şimdi uygulamanın kuyruk özyinelemesine izin veriliyor:

f(n):
   while n is not even do n = (n-1) / 2
   f(n) = n/2

Ve bu sonsuza kadar ve sadece n = -1 ise döngüler.


C, bu çağırma f(-1)undefined davranış olduğunu düşünüyorum (uygulama her iş parçacığı ya sonlandırır ya da bu işlevi yapmaz faaliyetleri kısa bir listede başka bir şey yapar varsayabilir), böylece derleyici aslında istediği her şeyi yapabilir durum!
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.