1. Temel Bilgiler
Brainfuck'ı anlamak için, 0her biri tarafından başlatılan sonsuz hücre dizisi hayal etmelisiniz .
...[0][0][0][0][0]...
Brainfuck programı başladığında herhangi bir hücreyi işaret eder.
...[0][0][*0*][0][0]...
İşaretçiyi sağa >hareket ettirirseniz, işaretçiyi X hücresinden X + 1 hücresine hareket ettirirsiniz.
...[0][0][0][*0*][0]...
Hücre değerini artırırsanız +şunları elde edersiniz:
...[0][0][0][*1*][0]...
Hücre değerini tekrar artırırsanız, +şunları elde edersiniz:
...[0][0][0][*2*][0]...
Hücre değerini düşürürseniz -şunları elde edersiniz:
...[0][0][0][*1*][0]...
İşaretçiyi sola <hareket ettirirseniz, işaretçiyi X hücresinden X-1 hücresine taşırsınız
...[0][0][*0*][1][0]...
2. Giriş
Karakteri okumak için virgül kullanırsınız ,. Yaptığı şey şudur: Standart girdiden karakteri okuyun ve ondalık ASCII kodunu gerçek hücreye yazın.
ASCII tablosuna bir göz atın . Örneğin, ondalık kodu !is 33, while ais 97.
Peki, BF program belleğinizin şöyle göründüğünü hayal edelim:
...[0][0][*0*][0][0]...
Standart girdinin yerini varsayarsak a, virgül ,operatörü kullanırsanız , BF'nin yaptığı şey, aondalık ASCII kodunu 97belleğe okumaktır :
...[0][0][*97*][0][0]...
Genelde böyle düşünmek istersiniz, ancak gerçek biraz daha karmaşıktır. Gerçek şu ki, BF bir karakter değil, bir bayt (o bayt ne olursa olsun) okur. Size örnek göstereyim:
Linux'ta
$ printf ł
baskılar:
ł
belirli bir cila karakteri. Bu karakter ASCII kodlamasıyla kodlanmamıştır. Bu durumda, UTF-8 kodlamasıdır, bu nedenle bilgisayar belleğinde birden fazla bayt alırdı. Onaltılık bir döküm yaparak bunu kanıtlayabiliriz:
$ printf ł | hd
hangi gösterir:
00000000 c5 82 |..|
Sıfırlar ofsettir. 82birinci ve c5temsil eden ikinci bayttır ł(sırayla onları okuyacağız). |..|bu durumda mümkün olmayan grafik gösterimdir.
Peki, łtek bayt okuyan BF programınıza girdi olarak geçerseniz , program belleği şöyle görünecektir:
...[0][0][*197*][0][0]...
Neden 197? Eh 197ondalık sayıdır c5onaltılık. Tanıdık geliyor mu? Elbette. İlk baytı ł!
3. Çıktı
Karakteri yazdırmak için nokta kullanırsınız .Ne yapar: Gerçek hücre değerini ondalık ASCII kodu gibi ele aldığımızı varsayarsak, karşılık gelen karakteri standart çıktıya yazdırın.
Peki, BF program belleğinizin şöyle göründüğünü hayal edelim:
...[0][0][*97*][0][0]...
Şimdi nokta (.) Operatörünü kullanırsanız, BF'nin yaptığı şey yazdırmaktır:
bir
Çünkü aASCII'deki ondalık kod 97.
Örneğin, bunun gibi BF programı (97 artı 2 nokta):
++++++++++++++++++++++++++++++++++++++++++++++++++ +++++++++++++++++++++++++++++++++++++++++++++++ ..
Gösterdiği hücrenin değerini 97'ye çıkaracak ve 2 kez basacaktır.
aa
4. Döngüler
BF döngüde döngü başlangıcı [ve döngü bitiminden oluşur ]. Koşulun gerçek hücre değeri olduğu C / C ++ 'da olduğu gibi düşünebilirsiniz.
Aşağıdaki BF programına bir göz atın:
++[]
++ gerçek hücre değerini iki kez artırır:
...[0][0][*2*][0][0]...
Ve []sanki while(2) {}sonsuz döngüdür.
Diyelim ki bu döngünün sonsuz olmasını istemiyoruz. Örneğin şunları yapabiliriz:
++[-]
Dolayısıyla, bir döngü her döngüde gerçek hücre değerini azaltır. Gerçek hücre değeri 0döngü bittiğinde:
...[0][0][*2*][0][0]... loop starts
...[0][0][*1*][0][0]... after first iteration
...[0][0][*0*][0][0]... after second iteration (loop ends)
Başka bir sonlu döngü örneğini ele alalım:
++[>]
Bu örnek, döngünün başladığı hücrede döngüyü bitirmemiz gerektiğini gösterir:
...[0][0][*2*][0][0]... loop starts
...[0][0][2][*0*][0]... after first iteration (loop ends)
Ancak başladığımız yerde bitirmek iyi bir uygulamadır. Neden ? Çünkü döngü başladığı başka bir hücreyi bitirirse, hücre işaretçisinin nerede olacağını varsayamayız. Dürüst olmak gerekirse, bu uygulama beyni daha az beyinsiz yapar.