专栏文章

文言文编程进阶

科技·工程参与者 198已保存评论 216

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
216 条
当前快照
1 份
快照标识符
@mhz5t4ax
此快照首次捕获于
2025/11/15 01:56
4 个月前
此快照最后确认于
2025/11/29 05:24
3 个月前
查看原文

序言

本文章主要是用以补充文言文浅谈的内容。
注:阅读前请先了解文言文浅谈的内容。
以最新版为准,不保证洛谷IDE支持全部内容。

Part 1 输入输出进阶

输出和输入是一切语言的基本操作。文言的输出简洁,输入则稍微繁琐。

输出

输出语句的标志:書之。
吾有一數。...書之。:输出数字,阿拉伯形式。
数字的范围是 [2256,2256)[-2^{256},2^{256})
其中...中,表示常量使用中文表示,也可使用变量形式。
如:吾有一數。曰三十七。書之。输出 3737
吾有一言。...書之。:输出字符串。
字符串表示为「「...」」形式。(注意有二层括号)
如:吾有一言。曰「「字符串」」。書之。输出字符串
以上每次“书之”语句的输出各占一行。为了在一行内输出多个数字,可以使用以下语句:
吾有三數。曰三千二百四十一。曰五百五十。曰一千零五。書之。
输出3241 550 1005

输入

输入由于还未设专门函数,使用Javascript函数完成。
先看一下A+B Problem给的输入:
CPP
施「require('fs').readFileSync」於「「/dev/stdin」」。名之曰「數據」。
施「(buf => buf.toString().trim())」於「數據」。昔之「數據」者。今其是矣。
施「(s => s.split(' '))」於「數據」。昔之「數據」者。今其是矣。
注曰。「「文言尚菜,無對象之操作,故需 JavaScript 之语法」」。

夫「數據」之一。取一以施「parseInt」。名之曰「甲」。
夫「數據」之二。取一以施「parseInt」。名之曰「乙」。
其中注曰之前的函数不用管(split除外)。
讲解:「(s => s.split(' '))」将数据拆分,以某个符号为界限(注意这个符号不在函数结果之内)。
「parseInt」将字符串转换为数字。
一些语法会在后提到。
先给一个得到一行数字的函数。
CPP
吾有一術。名之曰「输入」。是術曰。
    施「require('fs').readFileSync」於「「/dev/stdin」」。名之曰「入」。
    施「(buf => buf.toString().trim())」於「入」。昔之「入」者。今其是矣。
    施「(s => s.split('\n'))」於「入」。昔之「入」者。今其是矣。
    乃得「入」也。
是謂「输入」之術也。

吾有一數。曰零。名之曰「其行」。
施「输入」。名之曰「初始输入」。

吾有一術。名之曰「得数」。是術曰。
    吾有一列。名之曰「其数」。
    加「其行」以一。昔之「其行」者。今其是矣。
    夫「初始输入」之「其行」。名之曰「此行」。
    施「(s => s.split(' '))」於「此行」。昔之「此行」者。今其是矣。
    夫「此行」之長。名之曰「长」。
    吾有一數。曰零。名之曰「下标」。
    為是「长」遍。
        加「下标」以一。昔之「下标」者。今其是矣。
        夫「此行」之「下标」。名之曰「此数」。
        施「parseInt」於「此数」。昔之「此数」者。今其是矣。
        銜「其数」以「此数」。昔之「其数」者。今其是矣。
    云云。
    乃得「其数」也。
是謂「得数」之術也。
如果看过浅谈,应该不难理解:将初始输入用换行符拆分为各行;使用一个变量表示目前所在的行;每行要用时用空格拆分成各个小字符串;将小字符串转为数字后装入列表返回。

Part 2 变量

声明

吾有一數。曰一。名之曰「数」。声明数字。相当于int a=...
吾有一言。曰「「字符串」」。名之曰「文」。声明字符串。
吾有一爻。曰陽。名之曰「布尔型」。声明布尔型变量。
(布尔值表示:为真,为假)
吾有一元。...名之曰「自动类型」。声明的变量自动判断类型,相当于C++11的auto
也可以用这个形式:有數一。名之曰「数」。
多个变量同时声明:吾有三數。曰一。曰二。曰三。名之曰「数甲」曰「数乙」曰「数丙」。

自动变量

:最近的算出的答案。

使用

用括号「」括变量名。如「变量」
特别地,使用自动变量时不带括号。

赋值

...昔之「变量」者。今其是矣。赋前面最近所算出的答案。
昔之「变量」者。今...是矣。赋为此语句给出的值。相当于var=...

Part 3 运算

数字运算

加...以...。对应+运算。
减...以...。对应-运算。
乘...以...。对应*运算。
除...以...。对应/运算。注意此运算保留小数。
除...以...。所餘幾何。对应%(取模)运算。

大小关系判断

...大於...对应>运算。
...不大於...对应<=运算。
...小於...对应<运算。
...不小於...对应>=运算。
...等於...对应==运算。

布尔值运算

夫...中有陽乎。对应||(或)运算。
夫...中無陰乎。对应&&(与)运算。
如:夫「布尔值甲」「布尔值乙」中有陽乎。

Part 4 分支与循环

分支语句

CPP
若...(条件)者。
	...(真时代码块)
若非。(等同else,可选)
	...(假时代码块,可选)
云云。(if结束)
如:
CPP
若三不大於五者。
	吾有一言。曰「「想当然」」。書之。
若非。
	吾有一言。曰「「电脑出锅」」。書之。
云云。
相当于
CPP
if (3<=5) printf("of course");
else printf("bad computer");
或若...:相当于else if语句。
若其然者/若其不然者:当自动变量不为零/为零时执行语句。

循环语句

為是...(循环次数)遍。声明一个执行特定次的循环开始。
相当于for(i=0;i<n;++i)
恆為是。声明一个死循环的开始。可以用乃止。语句结束。
相当于for(;;)
云云。声明循环部分结束。(和分支语句一样)
乃止。跳出最内的一个循环,相当于break语句。
乃止是遍。返回到循环开始,相当于continue语句。

Part 5 数组

声明

吾有一列。名之曰「数组」。
相当于[类型未知] array={};
声明带赋值:吾有一列。名之曰「数组」。充「数组」以零。以一。
相当于[类型未知] array={0,1};

调用

查询数组内容:夫「数组」之...(下标)返回容器特定下标的值。下标从一开始。如夫「数组」之一夫「容器」之「「字符串」」
数组内容更改:昔之「数组」之...(下标)者。今...是矣。
查询数组大小:夫「数组」之長。
相当于list.size()
连接不同数组或数组与元素连接:銜「数组」以...(连接目标)。此函数将结果数组返回,不改变原有数组。
声明遍历数组内容的循环开始:凡「数组」中之「变量」。(也是云云。结束)
将数加在数组后面:充「数组」以一。 充「数组」以一。以二。
相当于array.push(1); array.push(1);array.push(2);

Part 6 函数

声明

函数声明开始:吾有一術。名之曰「函数」。是術曰。
相当于[返回值类型未知] function()
带参数:
吾有一術。名之曰「函数」。欲行是術。必先得一數。曰「参数」。是術曰。
相当于[返回值类型未知] function(int var_a)
吾有一術。名之曰「函数」。欲行是術。必先得...(参数个数)數。曰「参数一」。曰「参数二」。...(声明各种参数)是術曰。
注:这里的参数类型也可以是字符串()、布尔值等。
函数结束声明:是謂「函数」之術也。
格式:
CPP
吾有一術。名之曰「函数」。...(参数声明,可选)是術曰。
	...(函数内容)
是謂「函数」之術也。
比如这就是一个求线段树右儿子的函数(注意参数不是以指针形式传入的)
CPP
吾有一術。名之曰「其右」。欲行是術。必先得一數。曰「节点」。是術曰。
    乘「节点」以二。昔之「节点」者。今其是矣。
    加「节点」以一。昔之「节点」者。今其是矣。
    乃得「节点」也。
是謂「其右」之術也。
返回结果:乃得...(函数返回值)也。注意编译时它自带右括号,因此在分支或循环语句末尾时要处理(把云云。删去)。
当返回不带返回值时,使用乃歸空無。语句。

调用

函数的调用非常简洁。施「函数」。(无参)施「函数」於...。於...(代入各参数)(有参)
尽管函数声明时规定了参数个数,但是调用时参数个数可以少于规定个数。这将返回一个函数,表现为原函数前面一些参数固定的版本。
举例:
CPP
吾有一術。名之曰「修改」。欲行是術。必先得六數。曰「节点」。曰「左」。曰「右」。曰「改左」。曰「改右」。曰「增值」。是術曰。[1]
	...
是謂「修改」之術也。

...
施「修改」於一。於一。於「树长」。名之曰「简易修改」。[2]
...
施「简易修改」於「改左」。於「改右」。於「增值」。...[3]
说明:上面代码中[1]处声明了线段树的修改函数,其中有六个参数。考虑到主函数中调用此函数前三个参数是固定的,于是在[2]处通过不完全参数定义了新函数「简易修改」,调用简易版函数时([3])只用带入原函数的后三个参数就可以了。

Part 7 结构体

声明:吾有一物。名之曰「结构体」。
带内容声明:
CPP
吾有一物。名之曰「结构体」。其物如是。
    物之「「数」」者。數曰一。
    物之「「文」」者。言曰「「字符串」」。
    ...(声明结构体各个内容)
是謂「结构体」之物也。
用法与数组类似。

Part 8 标准库

调用标准库前声明:吾嘗觀「「...(库名)」」之書。方悟「...(调用函数名)」之義。声明后可以像正常函数一样调用。
也可以一次声明多个:吾嘗觀「「算經」」之書。方悟「正弦」「餘弦」之義。
调用特定文件的语法举例:吾嘗觀「「codes」」中「「luogu」」中「「p1001」」之書。调用codes/luogu/p1001

算經

算经库提供了一些数学函数。
部分标准库函数:
函数对应
取底除floor(a/b),同时返回商和余数
正負符号(1(正)0(零)-1(负))
取整除round(a/b)(四舍五入),同时返回商和余数
取底floor()
取整round()
取頂ceil()
絕對abs(),fabs()
正弦sin()
餘弦cos()
反正弦asin()
反餘弦acos()
正切tan()
反正切atan()
勾股求角atan2()
勾股求弦hypot()
對數log()
指數exp()
pow()
平方根sqrt()

易經

易经库提供了随机数。
函数对应
srand()
rand()

畫譜

书谱库提供了画图方法。画图在结构体上进行。
函数:備紙 擇筆 蘸色 落筆 運筆 提筆 裱畫。由于时间有限,故不再对这些函数深入研究。
最终图像输出:施「裱畫」於「图像」於「「out」」。

列經

提供了数组操作。这里只提供部分常用操作。
函数对应
遍施对数组内所有数x执行x=function(x)后返回
排序sort()
倒序reverse()

曆法

历法库提供时间操作。
今何紀元時 言今之日時 今年何年 今年何年號 今年何干支 今時何時 今時何小時 今刻何刻 今分何分 今秒何秒 等函数。很大一部分都是古人算法,现在不常用
调用言今之日時函数可以直接输出现在的时间。

Part 9 注释

注曰。「「注释内容」」。
批曰。「「注释内容」」。
疏曰。「「注释内容」」。
它们相当于其他语言中被/*,*/括起的注释。

Part 10 杂项

连接两个字符串:加「字符串甲」以「字符串乙」。相当于strcat(str_a,str_b);
宏定义: 或云「「宏名称」」。 蓋謂「「替换内容」」。
比如:或云「「書「甲」焉」」。 蓋謂「「吾有一言。曰「甲」。書之」」。
相当于#define output(str) cout<<str

异常处理(try-catch语句)

try语句:姑妄行此。表示需检测异常语句段开始。
throw语句:嗚呼。「「异常内容」」之禍。表示检测到异常,跳到catch段处理。相当于throw "error";
catch语句:如事不諧。表示检测到异常后执行的代码块开始。
catch语句内判断异常内容的特殊if语句:豈「「异常内容」」之禍歟。
上述特殊if语句对应的else不知何禍歟。
上述else获得具体异常信息:不知何禍歟。名之曰「异常信息」。
catch语句结束:乃作罷。
通俗点,就是先执行trycatch之间的代码,这一段代码中若满足一些条件使得其中的throw语句被执行了,那么忽略之后所有trycatch间的代码,执行catch段代码。如果没有,则catch段代码不被执行。

文言官方文件附带

  • 把代码渲染成古文样式(浅谈已说)
  • 将输出的数转为汉字的功能
  • 一些样例文件(官方IDE中可以找到)

Part 11 例子

A+B
CPP
施「require('fs').readFileSync」於「「/dev/stdin」」。名之曰「數據」。
施「(buf => buf.toString().trim())」於「數據」。昔之「數據」者。今其是矣。
施「(s => s.split(' '))」於「數據」。昔之「數據」者。今其是矣。

夫「數據」之一。取一以施「parseInt」。名之曰「甲」。
夫「數據」之二。取一以施「parseInt」。名之曰「乙」。

加「甲」以「乙」。書之。

总结

文言是一种广受欢迎的新生编程语言,优缺点总结如下:

优点

  • 对于中国人来说,代码可以作为注释,容易理解程序作用
  • 弘扬中华传统文化

缺点

  • 不方便输入,如一些繁体字、特殊括号等
  • 一些函数如输入还未完善

评论

216 条评论,欢迎与作者交流。

正在加载评论...