Quelqu'un m'a envoyé ça et a prétendu que c'était un bon monde dans Brainfuck (et je l'espère ...)
++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.
Je connais les bases que cela fonctionne en déplaçant un pointeur et en incrémentant et en décrémentant des trucs ...
Pourtant, je veux toujours savoir, comment ça marche réellement? Comment imprime-t-il quoi que ce soit à l'écran en premier lieu? Comment encode-t-il le texte? Je ne comprends pas du tout...
brainfuck
esoteric-languages
speeder
la source
la source
Réponses:
1. Bases
Pour comprendre Brainfuck, vous devez imaginer un tableau infini de cellules initialisées par
0
chacune.Lorsque le programme brainfuck démarre, il pointe vers n'importe quelle cellule.
Si vous déplacez le pointeur vers la droite,
>
vous déplacez le pointeur de la cellule X vers la cellule X + 1Si vous augmentez la valeur de la cellule,
+
vous obtenez:Si vous augmentez à nouveau la valeur de la cellule,
+
vous obtenez:Si vous diminuez la valeur de la cellule,
-
vous obtenez:Si vous déplacez le pointeur vers la gauche,
<
vous déplacez le pointeur de la cellule X vers la cellule X-12. Entrée
Pour lire le caractère, vous utilisez une virgule
,
. Ce qu'il fait est: Lire le caractère de l'entrée standard et écrire son code ASCII décimal dans la cellule réelle.Jetez un œil à la table ASCII . Par exemple, le code décimal de
!
est33
, tandis quea
est97
.Eh bien, imaginons que la mémoire de votre programme BF ressemble à:
En supposant que l'entrée standard signifie
a
, si vous utilisez l',
opérateur virgule , ce que fait BF est de lirea
le code ASCII décimal97
en mémoire:Vous voulez généralement penser de cette façon, mais la vérité est un peu plus complexe. La vérité est que BF ne lit pas un caractère mais un octet (quel que soit cet octet). Laissez-moi vous montrer un exemple:
Sous Linux
imprime:
qui est un caractère polonais spécifique. Ce caractère n'est pas encodé par encodage ASCII. Dans ce cas, il s'agit d'un codage UTF-8, il prenait donc plus d'un octet dans la mémoire de l'ordinateur. Nous pouvons le prouver en effectuant un vidage hexadécimal:
qui montre:
Les zéros sont décalés.
82
est le premier etc5
est le deuxième octet représentantł
(dans l'ordre nous les lirons).|..|
est une représentation graphique qui n'est pas possible dans ce cas.Eh bien, si vous passez
ł
comme entrée à votre programme BF qui lit un octet, la mémoire du programme ressemblera à:Pourquoi
197
? Eh bien, la197
décimale estc5
hexadécimale. Cela vous semble familier? Bien sûr. C'est le premier octet deł
!3. Sortie
Pour imprimer le caractère, vous utilisez le point
.
Ce qu'il fait est: En supposant que nous traitons la valeur réelle de la cellule comme du code ASCII décimal, imprimez le caractère correspondant sur la sortie standard.Eh bien, imaginons que la mémoire de votre programme BF ressemble à:
Si vous utilisez maintenant l'opérateur point (.), Ce que fait BF est d'imprimer:
Parce que
a
le code décimal en ASCII est97
.Par exemple, un programme BF comme celui-ci (97 plus 2 points):
Augmentera la valeur de la cellule pointée jusqu'à 97 et l'imprimera 2 fois.
4. Boucles
Dans BF, la boucle comprend le début
[
et la fin de la boucle]
. Vous pouvez penser que c'est comme en C / C ++ où la condition est la valeur réelle de la cellule.Jetez un œil au programme BF ci-dessous:
++
incrémente deux fois la valeur réelle de la cellule:Et
[]
c'est commewhile(2) {}
, donc c'est une boucle infinie.Disons que nous ne voulons pas que cette boucle soit infinie. On peut faire par exemple:
Ainsi, chaque fois qu'une boucle boucle, elle décrémente la valeur réelle de la cellule. Une fois que la valeur réelle de la cellule est
0
terminée, la boucle:Considérons encore un autre exemple de boucle finie:
Cet exemple montre que nous n'avons pas à terminer la boucle à la cellule sur laquelle la boucle a commencé:
Cependant, il est bon de terminer là où nous avons commencé. Pourquoi ? Parce que si la boucle termine une autre cellule qu'elle a commencée, nous ne pouvons pas supposer où sera le pointeur de cellule. Pour être honnête, cette pratique rend le brainfuck moins brainfuck.
la source
Wikipédia a une version commentée du code.
Pour répondre à vos questions, les caractères
,
et.
sont utilisés pour les E / S. Le texte est ASCII.L' article Wikipédia est également approfondi.
la source
,
et.
est utilisé pour les E / S, un peu comme C imprime en utilisantputchar
. Il s'agit d'un détail d'implémentation géré par le compilateur.Pour répondre à la question de savoir comment il sait quoi imprimer, j'ai ajouté le calcul des valeurs ASCII à droite du code où l'impression a lieu:
la source
Brainfuck identique à son nom. Il n'utilise que 8 caractères,
> [ . ] , - +
ce qui en fait le langage de programmation le plus rapide à apprendre mais le plus difficile à implémenter et à comprendre. … Et vous fait finalement finir par baiser votre cerveau.Il stocke les valeurs dans le tableau: [72] [101] [108] [111]
let, initialement pointeur pointant vers la cellule 1 du tableau:
>
déplacer le pointeur vers la droite de 1<
déplacer le pointeur vers la gauche de 1+
incrémenter la valeur de la cellule de 1-
incrémenter la valeur de l'élément de 1.
affiche la valeur de la cellule actuelle.,
prendre l'entrée à la cellule actuelle.[ ]
boucle, +++ [-] compteur de 3 comptes bcz il a 3 ′ + 'devant lui, et - décrémente la variable de comptage de 1 valeur.les valeurs stockées dans les cellules sont des valeurs ascii:
donc en se référant au tableau ci-dessus: [72] [101] [108] [108] [111] si vous correspondez aux valeurs ascii, vous constaterez que c'est Hello writtern
Félicitations! vous avez appris la syntaxe de BF
——- Quelque chose de plus ———
laissez-nous faire notre premier programme, à savoir Hello World , après quoi vous pourrez écrire votre nom dans cette langue.
briser en morceaux:
Crée un tableau de 4 cellules (nombre de>) et définit un compteur de 10 quelque chose comme: —-psuedo code—-
car la valeur du compteur est stockée dans la cellule 0 et> se déplace vers la cellule 1 met à jour sa valeur de + 7> se déplace vers la cellule 2 incrémente 10 à sa valeur précédente et ainsi de suite….
<<<
retourne à la cellule 0 et décrémente sa valeur de 1par conséquent, après la fin de la boucle, nous avons le tableau: [70,100,30,10]
passe au 1er élément et incrémente sa valeur de 2 (deux '+') puis imprime le caractère ('.') avec cette valeur ascii. ie par exemple en python: chr (70 + 2) # affiche 'H'
passe à la 2ème cellule incrément 1 à sa valeur 100 + 1 et affiche ('.') sa valeur ie chr (101) chr (101) # imprime 'e' maintenant il n'y a pas de> ou <dans la pièce suivante donc il prend la valeur actuelle du dernier élément et incrémenter uniquement
dernier élément = 101 donc, 101 + 7 et l'imprime deux fois (car il y a deux '..') chr (108) #prints l deux fois peut être utilisé comme
——— Où est-il utilisé? ——-
C'est juste un langage de plaisanterie conçu pour défier les programmeurs et n'est utilisé pratiquement nulle part.
la source
Toutes les réponses sont complètes, mais il leur manque un petit détail: l'impression. En construisant votre traducteur brainfuck, vous considérez également le personnage
.
, c'est en fait à quoi ressemble une déclaration d'impression dans brainfuck. Donc, ce que votre traducteur brainfuck devrait faire, c'est qu'à chaque fois qu'il rencontre un.
caractère, il imprime l'octet actuellement pointé.Exemple:
supposons que vous ayez ->
char *ptr = [0] [0] [0] [97] [0]
... s'il s'agit d'une déclaration brainfuck:>>>.
votre pointeur doit être déplacé de 3 espaces vers la droite pour atterrir à:,[97]
alors maintenant*ptr = 97
, après avoir fait cela, votre traducteur rencontre a.
, il devrait alors appelerou toute instruction d'impression équivalente pour imprimer l'octet actuellement pointé, qui a la valeur 97 et la lettre
a
sera alors imprimée sur lestd_output
.la source
Je pense que ce que vous demandez, c'est comment Brainfuck sait quoi faire avec tout le code. Il existe un analyseur écrit dans un langage de niveau supérieur tel que Python pour interpréter ce que signifie un point ou ce que signifie un signe d'addition dans le code.
Ainsi, l'analyseur lira votre code ligne par ligne, et dira ok il y a un symbole> donc je dois avancer l'emplacement de la mémoire, le code est simplement, if (contenu dans cet emplacement de mémoire) ==>, memlocation = + memlocation qui est écrit dans un langage de niveau supérieur, de même si (contenu de l'emplacement mémoire) == ".", puis print (contenu de l'emplacement mémoire).
J'espère que cela clarifie les choses. tc
la source