'Koşullu Dallanma - 'GoTo' Kluge ? - sayfa 4

 

Java da sanal makinesinin dışında çalışmıyor, orada aynı sorunları yaşayacaksınız, bir C programından yüklenebilen ve çağrılabilen bir dll yapamazsınız.

C#'ı seviyorsanız, ObjectPascal'ı da seveceksiniz (tür güvenliği, katılık, VM olayı dışında arkasındaki tüm felsefe). Sonuçta, C#'ın tasarımcısı ve baş mimarı, bir zamanlar Turbo-Pascal ve Delphi'yi (ObjectPascal) yaratan kişiyle aynı kişidir ve bu, parıldamaktadır. Bazı açılardan C#, (çirkin ama günümüzde modern) C sözdizimine sahip ObjectPascal gibidir.

Doğrudan makineyle ve C-API'lerle (MetaTrader için gerekli olduğu gibi) arabirim oluşturmak ve yine de C# kadar güçlü bir dil kullanmak için ObjectPascal'ın pek fazla alternatifi yoktur. Bazıları C++'ın eşit derecede güçlü olduğunu söylüyor (ve tabii ki OP yerine de kullanılabilir), ancak açıkça o kadar zarif değil, birçok tutarsızlığı var ve yalnızca gerçek uzmanların gerçekten ustalaşabileceği kadar hataya açık.

 
7bit :

.... bir fonksiyonun içindeki dönüş, fonksiyonun çağrıldığı yere dönmesini sağlayacaktır.

Bu önemli ayrım 7bit: Tamamen farklı bir işlevi, alt rutini veya hatta içe aktarılan kodu, tüm alt rutinleri ve/veya mevcut işlevin DIŞINDAKİ işlevleri çağırmaktan bahsediyorum. Kavramsal bir örnek:

100. satırdan 20. satıra kadar yer alan bir işlevdeyim, ancak BU kapsamın dışında kalan bir şeyi çağırmak istiyorum. Belki de 50'den 60'a kadar olan satırlarda olan tamamen farklı bir fonksiyon. <=-Bu, yukarıdaki parametrelere ve örneğe uymuyor ki bu benim sorduğum şey Eski gosub/dönüşün %100 ikamesidir ve ayrıca fonksiyon izin verir değerleri geçmek ve değerleri döndürmek için.

Aynı fonksiyon içinde birden fazla dönüş ifadesine sahip olabilirsiniz ve ayrıca break ile döngülerden çıkabilirsiniz ....

Anladım

Ancak, anladığım belirli bir işlev kapsamında nasıl hareket edebileceğim konusunda sürekli bilgi alıyorum. Ama benim sorduğum ve tüm bunların başında belirttiğim şey bu DEĞİLDİR .

Yani 'istisnalar'a gelince, dilerseniz onlara öyle diyebilirsiniz sanırım. Belirttiğim gibi, doğrudan MQL4 içinde bir fonksiyon olarak mevcut olmayan GoTo, GoSub (CURRENT fonksiyonunun dışında) vb. fonksiyonların fonksiyonlarını eklemek ve kullanmak için bir 'çözüm' bulmaya çalışıyorum. Yanıtlarınıza göre, çoğunuz bu programlama ayrımlarını biliyor ve anlıyorsunuz, ancak sorulan asıl soruyu ele almıyorsunuz.

 

FourX :

100. satırdan 20. satıra kadar yer alan bir işlevdeyim, ancak BU kapsamın dışında kalan bir şeyi çağırmak istiyorum. Belki de 50'den 60'a kadar olan satırlarda tamamen farklı bir işlev.
50 - 60 satırlarındaki kodu içeren ayrı bir işlev oluşturun, ardından istediğiniz zaman hangi işlevde olursanız olun onu çağırabilirsiniz.
 

bunu düşün:

 void foo(){
   int x;
   int y;
  y = 33 ;
  x = 42 ;
  .LABELFOO
  print(x);
   return ;
}

void bar(){
   int x;
  z = 5 ;
  GOTO .LABELFOO
}

void main(){ //<-- program starts here
  foo();
  bar();
}

Şimdi ne olacak? Main() ile başlayalım, yürütme sırasındaki tüm adımları açıklayacağım (yorumlar yeşil , talimatlar siyah ):

  • (main()'de ilk satırdayız)
  • dönüş adresini yığının üzerine itin (4 bayt gerekir), bu, foo() çağrısı bittiğinde devam edeceği adrestir (daha sonra nereye döneceğimizi bilmemiz için bunu hatırlamamız gerekir)
  • foo() öğesinin ilk satırına atla
  • yerel değişken x'e yer açmak için 4 baytı yığına itin
  • yerel değişken y'ye yer açmak için yığına 4 bayt itin
  • (yığınımız şimdi 12 bayt yüksekliğinde)
  • 33 uzun değerini bayt 0,1,2,3'e yazın (yığının tepesinden sayılır)
  • 42 uzun değerini bayt 4,5,6,7'ye yazın (yığının tepesinden sayılır)
  • 4,5,6,7 baytlarında bulunan uzun değeri yazdırın (yığının tepesinden sayılır)
  • yığından 4 bayt çıkar ve onları unut (y kapsam dışına çıkar)
  • yığından 4 bayt çıkar ve onları unut (x kapsam dışına çıkar)
  • yığından 4 bayt çıkar, bu şimdi dönüş adresi olan foo()'yu çağırırken geldiğimiz adres, bu adrese atla
  • (şimdi bir sonraki satırda, bar() ile main()'e geri döndük)
  • dönüş adresini (4 bayt) yığına itin
  • çubuğun ilk satırına atla()
  • yığına 4 bayt (yerel değişken x) itin
  • (yığınımız şimdi 8 bayt yüksekliğinde)
  • 5 uzun değerini bayt 0,1,2,3'e yazın (yığının üstünden sayılır)
  • etikete atla .LABELFOO
  • (şimdi buradan itibaren her şeyin nasıl korkunç bir şekilde ters gittiğini dikkatlice gözlemleyin. Aşağıdaki satırların hepsinin ne yapacağını zaten biliyoruz çünkü yukarıda açıkladım, daha önce yaptıklarının aynısını yapıyorlar, hepsi üstteymiş gibi davranıyorlar. Yığının 12 byte'ı onların emrinde.Ama yığının bu sefer sadece 8 byte'ı var!Bir sonraki satır yığının tepesinden 4,5,6,7 konumunda bir değişken bekliyor, şimdi bakalım ne olacak, işte geliyor baskı ile satır)
  • 4,5,6,7 baytlarında bulunan uzun değeri yazdırın (yığının tepesinden sayılır)
  • (ayy? bu bizim x değil, bu dönüş değeri, yığın bu sefer sadece 8 bayt yüksekliğinde, toplam saçma bir sayı yazdırıyor)
  • yığından 4 bayt çıkar ve onları unut (bu "y kapsam dışına çıkar" olur ama bu y değil, aslında diğer işlevdeki x'tir)
  • yığından 4 bayt çıkar ve onları unut (bu "x kapsam dışına çıkıyor" olur ama x değil, dönüş adresini attık!)
  • (yığın şimdi boş!)
  • dönüş adresini almak için yığından 4 bayt çıkar -> kilitlenme!

Bunu görebiliyor musun? foo işlevi, 8 baytlık bir yerel yığın çerçevesi artı dönüş adresi ve bar işlevi yalnızca 4 baytlık artı bir dönüş adresi gerektirir. Geri dönüş ifadeleri, derleyici tarafından derleme zamanında zaten yerleşiktir, yığından farklı miktarlarda bayt çıkarırlar, bir dönüşü diğerinin işini yapmak için kullanamazsınız, her biri yalnızca derlendiği işlev için çalışır.

Programın tamamında GOTO'ya sahip olan bu eski diller yerel değişken kapsamına sahip değildi ve doğru yapmanız gereken tek şey GOSUB ve RETURN sayılarını eşitlemekti, tüm geri dönüşleri yalnızca dönüş adresini ve başka hiçbir şeyi açmadı. , tüm dönüşler tamamen aynı şekilde davrandı. Ama şimdi elimizde birçok farklı boyutta "GOSUB" var (her biri yığına farklı miktarlar itiyor) ve ayrıca yığından farklı miktarlarda çıkan birçok farklı getiri var. Ve yığında yerel değişkenlerimiz var. Derleyicide ne kadar çılgın şeyler oluşturmaya çalışırsanız çalışın, bu işe yaramaz.

Teorik olarak *aynı* işlev içinde GOTO yapabilirsiniz (ve bazı diller buna izin verir), ancak bunun doğru yapılandırılmış programlamadan daha zarif ve anlaşılması daha kolay ve daha sürdürülebilir koda yol açacağı tek bir kod parçası gösteremezsiniz. Yapacağı tek şey korkunç bir karmaşa yaratmak. Kimsenin buna ihtiyacı yok, bu yüzden uygulanmadı.

 

MQL4'ün GoTo VEYA ' GoSub -=> ReturnFromGoSub ' gibi yerel işlevleri olmadığını zaten biliyoruz. Bu konuda bir anlaşmazlık yok. Bu artık MQL4'ün bu tür yerel işlevlere sahip olmadığı gerçeğinin tekrarlanan açıklamalarına ve örneklerine dönüştü. Orada tartışma yok. Bu dizinin konusu bu değil ve hiçbir zaman da olmadı. O halde lütfen zaten bildiğimiz ve üzerinde anlaştığımız şeyler hakkında tartışmayı bırakabilir miyiz?

Bunların diğer programlama dillerinde geçerli fonksiyonlar olduğunu ve çok faydalı olabileceğini biliyoruz.

Bunun bütün amacı, MQL4'te mevcut olanlarla bunları simüle edip kullanıp kullanamayacağımızı bulmaktır.

Örneğin, ' GoSub -=> ReturnFromGoSub ' ifadesinin ilk cümlesindeki ikinci durumun geçerli bir işlev tamamlaması şu olacaktır: GoSub'ın çağrıldığı programın noktasına geri dönün ve GoSub'dan gelen değerleri programı.

 
FourX :

Örneğin, ' GoSub -=> ReturnFromGoSub ' ifadesinin ilk cümlesindeki ikinci durumun geçerli bir işlev tamamlaması şu olacaktır: GoSub'ın çağrıldığı programın noktasına geri dönün ve GoSub'dan gelen değerleri programı.


Size defalarca tanımladığınız şeyin bir Özel İşlev olduğu söylendi. . . bunu neden kabul edemiyorsun? lütfen neden Özel İşlev != Gosub + Return'ün sözde kodla bir örnek verin
 

FourX :

' GoSub -=> ReturnFromGoSub ' şöyle olacaktır: GoSub'ın çağrıldığı programın noktasına dönün ve GoSub'dan programdaki çağrı noktasına değerleri döndürün.

 double subtract_two_numbers( double a, double b){
  Print( "will now calculate " , a, " minus " , b);
   return (a - b);                                 // <---- THIS IS YOUR RETURN
}

int start(){                                     // <---- PROGRAM STARTS HERE
  double s;
   double d;

  s = subtract_two_numbers(Ask, Bid);            // <---- THIS IS YOUR GOSUB
  d = subtract_two_numbers(Close[ 0 ], Open[ 0 ]);   // <---- THIS IS YOUR GOSUB

  Print( "the spread is " , s);
  Print( "price moved " , d, " since the open" );
}                                                // <---- PROGRAM ENDS HERE
Orada, Commodore-BASIC'te veya sürekli olarak karşılaştırmaya çalıştığınız diğer eski ve sakat dillerde bile mümkün olmayan argümanlar ve dönüş değerleri ile bile, doğrudan mql4 diline yerleştirilmiş GOSUB ve RETURN'e sahipsiniz. Son 30 yılda neredeydin?
 

FourX, mql4 öğreniyor ve aklınız hala BBC Basic'teyse, defproc ve proc'u düşünün ve GoTo ve GoSub'ı unutun.

80'lerin başında bir BBC mikro cihazım vardı ....ahhhh, programları kaset sürücüsünden yüklemeye çalışmanın zevkini hala hatırlıyorum :( eskiden BBC Basic'te programlar yazardık

 
SDC :

FourX, mql4 öğreniyor ve aklınız hala BBC Basic'teyse, defproc ve proc'u düşünün ve GoTo ve GoSub'ı unutun.

80'lerin başında bir BBC mikro cihazım vardı ....ahhhh, programları kaset sürücüsünden yüklemeye çalışmanın zevkini hala hatırlıyorum :( eskiden BBC Basic'te programlar yazardık

ÇOK KOMİK . . . Acorn Electron'um vardı. . . hava sıcakken, soğukken yazdığım banttan bir şeyler okumazdı ve tam tersi. . . Hey gidi günler. ;-)
 
RaptorUK :
ÇOK KOMİK . . . Acorn Electron'um vardı. . . hava sıcakken, soğukken yazdığım banttan bir şeyler okumazdı ve tam tersi. . . Hey gidi günler. ;-)

Evet, iyi günlerdi :) bükük bir tornavidayı bant başlarındaki o küçük vidanın üzerinde bükerken bir yandan da yanlarına tekrar tekrar vurarak haha
Neden: