c 程序设计(编程大神竟玩出了不像)
c 程序设计(编程大神竟玩出了不像)$ cc -E cpaint.c | clang-format | less如果你感兴趣的话,不妨去试试上面的程序吧!如果想查看 C 代码的真实外观,请尝试运行:#include"cpaint.h"var a b c h i l v x y q w p size 65535 ,packed n size 13 ꞉integer ;procedure display(r s c) ;begin LOOP call A(Z) ; call H(y x) ; call B(Z) POOL ; y ꞉= r; x ꞉= s; call A(c) ; call H(y x) ; call B(c) ; call refreshend ;procedure fill(y x c a) ;begin if(y<0 or y>w-1 or x<0 or x>q
作者 | Brian Robert Callahan
编译 | 张洁 责编 | 屠敏
为了让挑战变得有意思,Brian Robert Callahan(纽约州北部伦斯勒理工学院信息技术和网络科学的讲师) 决定编写一个看起来一点也不像 C 的 C 程序。如果把 C 语言变成另一种语言,然后用那种语言去编写程序,那么使用 C 编译器编译程序会怎样?
能编写出以下程序,Brian Robert Callahan 觉得是一件很光辉的事。
#include"cpaint.h"
var a b c h i l v x y q w p size 65535 ,
packed n size 13 ꞉integer ;
procedure display(r s c) ;
begin
LOOP
call A(Z) ;
call H(y x) ;
call B(Z)
POOL ;
y ꞉= r;
x ꞉= s;
call A(c) ;
call H(y x) ;
call B(c) ;
call refresh
end ;
procedure fill(y x c a) ;
begin
if(y<0 or y>w-1 or x<0 or x>q-1 or c = a or Z <> a)fill꞉= -1 ;
call draw(c) ;
call fill(y 1 x c a) ;
call fill(y-1 x c a) ;
call fill(y x-1 c a) ;
call fill(y x 1 c a)
end ;
procedure save(r s) ;
begin
i ꞉= 0 ;
while(i<13)do
begin
n[i] ꞉= 0 ;
i ꞉= i 1
end ;
call move(w>>1 (q>>1)-6) ;
call printw("Save: ") ;
call echo ;
call getnstr(n 12) ;
call noecho ;
call open(n "w ") ;
call writeChar(83) ;
call writeChar(w) ;
call writeChar(q) ;
LOOP
call writeChar(Z)
POOL ;
y ꞉= r;
x ꞉= s;
call close ;
call move(y x)
end ;
procedure load(packed ʌ n) ;
begin
call open(n "r") ;
call check ;
LOOP
readln(c);
call draw(c)
POOL ;
c ꞉= 0;
call close
end ;
procedure m ;
begin
l ꞉= 0 ;
v ꞉= 1 ;
call A(c) ;
call H(0 0) ;
call B(c) ;
call refresh ;
while(v)do
begin
read(inp) ;
'/':l ꞉= not l ; if(l)call draw(c) ; OK
'k':y ꞉= y-1 ; if(y<0)y ꞉= 0 ; if(l)call draw(c) ; OK
'j':y ꞉= y 1 ; if(y>w-1)y ꞉= w-1 ; if(l)call draw(c) ; OK
'h':x ꞉= x-1 ; if(x<0)x ꞉= 0 ; if(l)call draw(c) ; OK
'l':x ꞉= x 1 ; if(x>q-1)x ꞉= q-1 ; if(l)call draw(c) ; OK
' ':call draw(c) ; OK
'c':c ꞉= c 1 ; if(c = M)c ꞉= 0 ; OK
'd':call draw(15) ; OK
'f':call fill(y x c Z) ; OK
's':call save(y x) ; OK
'q':v ꞉= 0 ; OK
'v':c ꞉= c-1 ; if(c = N)c ꞉= M-1 ; CALL display(y x c)
end
end ;
procedure main(I c packed ʌ ʌ v) ;
begin
call start ;
call getmaxyx(stdscr w q) ;
if(w>M)w ꞉= M ;if(q>M)q ꞉= M ;
call start_color ;
while(x<M)do
begin
call init_pair(x x x) ;
x ꞉= x 1
end ;
LOOP
call draw(15)
POOL ;
if(c = 2)call load(v[c-1]) ; call display(0 0 0) ; call m ; call endwin
end ;
call main.
通过这段代码,也许有很多网友直言,这并非是 C 代码,而是包含 Pascal 语言的所有特征,用分号作为语句分隔符而不是语句结束符,用“:=”表示赋值,也许还有一些 Algol(一种指令式编程语言)的 LOOP……POOL 语法。它甚至有 Pascal 语言的返回赋值,即给函数分配一个值,就是它的返回值。
不过,Brian Robert Callahan 对此解释道,最近听说 A 、K 和 Q 语言(它们是 APL 和 J 之类的数组编程语言)的开发者 Arthur Whitney 会使用 C 预处理器来创建自己的语言,然后用这种自定的语言来实现他的语言。于是,他决定尝试一下这个有趣的实验。
Brian Robert Callahan 基于 PL/0 的自定义语言,编写了一个编译器。这个练习的亮点是 C 编译器将 UTF-8 字符理解为标识符的有效字符。Brian Robert Callahan 使用了很多看起来像 ASCII(美国信息交换标准代码)的字符,实际上并不是 ASCII,最终还是被接受为有效的标识符。C 预处理器能很好地将这些标识符转化为相对应的指令。在这里可以看到隐藏起来的头文件。
如果想查看 C 代码的真实外观,请尝试运行:
$ cc -E cpaint.c | clang-format | less
如果你感兴趣的话,不妨去试试上面的程序吧!
原文链接:https://briancallahan.net/blog/20220220.html