目录
请先看此文章!
大家了解之后,可能会想:这么简单的语言,能不能用代码写出一个Brainfuck呢?
哈哈,当然可以!作为第一次发布文章的博主,就来帮帮你吧!
初始化:
#include <iostream>
#include <fstream>
#include <string>
//范围越大,能存放的数就越多,如果要存放很多数,就要把范围设得大一些
#define width 100000
//读入字符
std::string str;
//存放指针对应的数字和指针
int f[width], p = width / 2;
//要先把要编译的Brainfuck代码放入Brainfuck.txt
std::ifstream is ("Brainfuck.txt");
int main ()
{
//主算法……
return 0;
}
主算法:
先来一个while读入字符,在一个一个遍历str里的字符,最后判断每一个字符是什么
while (is >> str)
{
for (int i = 0; i < str.size (); ++i)
{
switch (str[i])
{
case '>': ++p; break;
case '<': --p; break;
case '+': ++f[p]; break;
case '-': --f[p]; break;
case '.': printf ("%c", f[p]); break;
case ',': f[p] = getchar(); break;
default: break;//可以不加,让大家看得清晰点
}
}
}
前面六个运算符都很简单,但最后的循环运算符[ ]就比较难了
思路:
因为再程序确保无误的情况下,[ 肯定是先出现的,那我们再在判断字符是不是"[",如果是,那就调用loop函数
在loop函数中,需要输入一个实参:指针,告诉函数要从哪里开始便历
case '[' : loop (i + 1); break;
loop函数的遍历和刚才的遍历差不多,不过在循环的过程中,需要检测每个字符是不是"]",如果是,再判断指针对应的数值是否为0,是那就退出函数,不是就继续循环
void loop(int pp)
{
int i;
for (i = pp; str[i] != ']'; ++i)
{
switch (str[i])
{
case '>': ++p; break;
case '<': --p; break;
case '+': ++f[p]; break;
case '-': --f[p]; break;
case '.': printf("%c", f[p]); break;
case ',': loop(i + 1); break;
}
}
if (f[p] != 0)
{
loop(pp);
}
}
注意!
如果str被遍历完了,就要在读入str,要不然程序会出现错误
void loop(int pp)
{
int i;
for (i = pp; str[i] != ']'; ++i)
{
if (i == str.size ())
{
is >> str;
i = 0;
}
switch (str[i])
{
case '>': ++p; break;
case '<': --p; break;
case '+': ++f[p]; break;
case '-': --f[p]; break;
case '.': printf("%c", f[p]); break;
case ',': f[p] = getchar(); break;
case '[': loop(i + 1); break;
}
}
if (f[p] != 0)
{
loop(pp);
}
}
这个程序还有一个漏洞,那就是当函数调用完之后,指针还指着"["的下一个,所以还得在修改一下
int loop(int pp)
{
int i;
for (i = pp; str[i] != ']'; ++i)
{
if (i == str.size ())
{
is >> str;
i = 0;
}
switch (str[i])
{
case '>': ++p; break;
case '<': --p; break;
case '+': ++f[p]; break;
case '-': --f[p]; break;
case '.': printf("%c", f[p]); break;
case ',': f[p] = getchar(); break;
case '[': i = loop(i + 1); break;
}
}
if (f[p] != 0)
{
loop(pp);
}
return i;
}
完整代码:
#include <iostream>
#include <fstream>
#include <string>
#define width 100000
std::string str;
int f[width], p = width / 2;
std::ifstream is ("Brainfuck.txt");
int loop(int pp)
{
int i;
for (i = pp; str[i] != ']'; ++i)
{
if (i == str.size ())
{
is >> str;
i = 0;
}
switch (str[i])
{
case '>': ++p; break;
case '<': --p; break;
case '+': ++f[p]; break;
case '-': --f[p]; break;
case '.': printf("%c", f[p]); break;
case ',': f[p] = getchar(); break;
case '[': i = loop(i + 1); break;
}
}
if (f[p] != 0)
{
loop(pp);
}
return i;
}
int main ()
{
while (is >> str)
{
for (int i = 0; i < str.size (); ++i)
{
switch (str[i])
{
case '>': ++p; break;
case '<': --p; break;
case '+': ++f[p]; break;
case '-': --f[p]; break;
case '.': printf ("%c", f[p]); break;
case ',': f[p] = getchar(); break;
case '[': i = loop(i + 1); break;
default: break;
}
}
}
return 0;
}
补充
我们还可以做一个程序:输入字符串,然后程序就会将字符串转为“Brainfuck”语言,存放在“Brainfuck.txt”里
程序如下
#include <iostream>
#include <fstream>
std::ofstream os ("Brainfuck.txt");
std::string str = "Hello, world";
void print (char ch)
{
for (int i = 1; i <= ch; ++i)
{
os << '+';
}
os << ".>" << std::endl;
}
int main ()
{
std::cin >> str;
for (char ch : str)
{
print (ch);
}
return 0;
}
完结
作者是首次发布文章,如文章有问题请小喷~