• 编程大师竟“玩”出了不像 C 的 C 程序


    作者 | Brian Robert Callahan

    编译 | 张洁

    责编 | 屠敏

    为了让挑战变得有意思,Brian Robert Callahan(纽约州北部伦斯勒理工学院信息技术和网络科学的讲师) 决定编写一个看起来一点也不像 C 的 C 程序。如果把 C 语言变成另一种语言,然后用那种语言去编写程序,那么使用 C 编译器编译程序会怎样?

    能编写出以下程序,Brian Robert Callahan 觉得是一件很光辉的事。

    1. #include"cpaint.h"
    2. var a, b, c, h, i, l, v, x, y, q, w, p size 65535
    3. packed n size 13 ꞉integer ;
    4. procedure display(r,s,c) ;
    5. begin
    6. LOOP
    7. call A(Z) ;
    8. call H(y,x) ;
    9. call B(Z)
    10. POOL ;
    11. y ꞉= r;
    12. x ꞉= s;
    13. call A(c) ;
    14. call H(y,x) ;
    15. call B(c) ;
    16. call refresh()
    17. end ;
    18. procedure fill(y,x,c,a) ;
    19. begin
    20. if(y<0 or y>w-1 or x<0 or x>q-1 or c = a or Z <> a)fill꞉= -1 ;
    21. call draw(c) ;
    22. call fill(y+1,x,c,a) ;
    23. call fill(y-1,x,c,a) ;
    24. call fill(y,x-1,c,a) ;
    25. call fill(y,x+1,c,a)
    26. end ;
    27. procedure save(r,s) ;
    28. begin
    29. i ꞉= 0 ;
    30. while(i<13)do
    31. begin
    32. n[i] ꞉= 0 ;
    33. i ꞉= i+1
    34. end ;
    35. call move(w>>1,(q>>1)-6) ;
    36. call printw("Save: ") ;
    37. call echo() ;
    38. call getnstr(n,12) ;
    39. call noecho() ;
    40. call open(n,"w+") ;
    41. call writeChar(83) ;
    42. call writeChar(w) ;
    43. call writeChar(q) ;
    44. LOOP
    45. call writeChar(Z)
    46. POOL ;
    47. y ꞉= r;
    48. x ꞉= s;
    49. call close ;
    50. call move(y,x)
    51. end ;
    52. procedure load(packed ʌ n) ;
    53. begin
    54. call open(n,"r") ;
    55. call check ;
    56. LOOP
    57. readln(c);
    58. call draw(c)
    59. POOL ;
    60. c ꞉= 0;
    61. call close
    62. end ;
    63. procedure m() ;
    64. begin
    65. l ꞉= 0 ;
    66. v ꞉= 1 ;
    67. call A(c) ;
    68. call H(0,0) ;
    69. call B(c) ;
    70. call refresh() ;
    71. while(v)do
    72. begin
    73. read(inp) ;
    74. '/':l ꞉= not l ; if(l)call draw(c) ; OK
    75. 'k':y ꞉= y-1 ; if(y<0)y ꞉= 0 ; if(l)call draw(c) ; OK
    76. 'j':y ꞉= y+1 ; if(y>w-1)y ꞉= w-1 ; if(l)call draw(c) ; OK
    77. 'h':x ꞉= x-1 ; if(x<0)x ꞉= 0 ; if(l)call draw(c) ; OK
    78. 'l':x ꞉= x+1 ; if(x>q-1)x ꞉= q-1 ; if(l)call draw(c) ; OK
    79. ' ':call draw(c) ; OK
    80. 'c':c ꞉= c+1 ; if(c = M)c ꞉= 0 ; OK
    81. 'd':call draw(15) ; OK
    82. 'f':call fill(y,x,c,Z) ; OK
    83. 's':call save(y,x) ; OK
    84. 'q':v ꞉= 0 ; OK
    85. 'v':c ꞉= c-1 ; if(c = N)c ꞉= M-1 ; CALL display(y,x,c)
    86. end
    87. end ;
    88. procedure main(I c,packed ʌ ʌ v) ;
    89. begin
    90. call start ;
    91. call getmaxyx(stdscr,w,q) ;
    92. if(w>M)w ꞉= M ;if(q>M)q ꞉= M ;
    93. call start_color() ;
    94. while(x<M)do
    95. begin
    96. call init_pair(x,x,x) ;
    97. x ꞉= x+1
    98. end ;
    99. LOOP
    100. call draw(15)
    101. POOL ;
    102. if(c = 2)call load(v[c-1]) ; call display(0,0,0) ; call m() ; call endwin()
    103. end ;
    104. 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

    如果你感兴趣的话,不妨去试试上面的程序吧!

    原文链接:Brian Robert Callahan

  • 相关阅读:
    史上最详细vue的入门基础
    Vue系列(一)之 Vue入门,Vue的生命周期以及前后端分离介绍
    Part2_扩展MATSIM_Subpart2_Mobsim_第11章 QSim
    渗透测试工程师
    适用于细胞核、细胞膜、线粒体、细胞骨架的成像的荧光探针推荐
    钉钉机器人发送折线图卡片 工具类代码
    把JS中的map方法玩出花来
    flutter开发实战-长按TextField输入框cut、copy设置为中文复制、粘贴
    技术对接51
    华为OD机试真题-5G网络建设
  • 原文地址:https://blog.csdn.net/m0_66862559/article/details/123073539