Dc (程序)

title: 历史.
content: dc是幸存的最老的Unix语言。在贝尔实验室收到第一台PDP-11的时候,用B语言写成的dc是在这个新机器上运行的第一个语言,甚至在汇编器之前。
title: 基本操作.
content: 在dc中要做4和5的乘法:  $ dc 4 5 * p 20 q  这可转译为“把4和5压入栈顶,通过乘法算符,从栈中弹出两个元素,将二者相乘并把结果压回栈顶”。接着使用codice_1命令打印栈顶的元素。使用codice_2命令退出此次调用的dc实例。注意数值相互间必须以空白分隔,但某些算符可以不必如此。 还可以用如下命令得到这个结果:  $ dc -e '4 5 * p' 20 $ echo "4 5 * p" |dc 20 $ dc - 4 5*pq 20 $ cat «EOF > cal.txt 4 5 * p EOF $ dc cal.txt 20  使用命令codice_3来变更算术精度,它设置算术运算的小数位数。因为缺省精度是codice_4,例如:  $ dc -e "2 3 / p" 0  通过使用命令codice_3调整精度,可以产生任意数目的小数数位,例如:  $ dc -e "5 k 2 3 / p".66666  dc有科学计算器的基本运算功能,比如求formula_1的值:  $ dc -e "2k 12 _3 4 ^ + 11 / v 22 - p" -19.10  其中,codice_6用于输入负数,codice_7计算幂,codice_8计算平方根。  使用codice_9命令复制栈顶元素。使用codice_10命令对栈顶和仅次栈顶的两个元素进行对换。使用codice_11命令压入当前栈深度,即执行codice_11命令前栈中元素的数目。
title: 输入/输出.
content: 使用codice_13命令,从stdin读取一行并执行它。这允许从宏中向用户要求输入,故而此输入必须是语法上正确的,并且这有潜在的安全问题,因为dc的codice_14命令可以执行任意系统命令。  前面提及过,codice_1命令打印栈顶元素,带有随后的一个换行。codice_16命令弹出栈顶元素并输出它,没有尾随换行。codice_17命令打印整个栈,一项一行。  dc还支持控制输入和输出的基数。codice_18命令弹出栈顶元素并将它用作输入基数。十六进制数字必须大写以避免和dc命令冲突,输入基数必须在2和16之间,输出基数必须大于等于2。codice_19命令设置输出基数,要记住输入基数将影响对后面的所有数值的分析,所以通常建议先设置输出基数。例如将二进制转换成十六进制:  $ echo 16o2i 11011110101011011011111011101111p | dc DEADBEEF  要读取设置的这些数值,codice_20、codice_21和codice_22命令将压入当前精度、输入基数和输出基数到栈顶。
title: 语言特征.
content: 除了上述的基本算术和栈操作,dc包括了对宏、条件和存储结果用于以后检索的支持。
title: 寄存器.
content: 寄存器在dc中是有着单一字符名字的存贮位置,它可以通过命令来存储和检索,它是宏和条件的底层机制:codice_23弹出栈顶元素并将它存储入寄存器codice_24,而codice_25将寄存器codice_24的值压入栈顶。例如: <syntaxhighlight> </syntaxhighlight> 寄存器还被当作次要栈,可以使用codice_27和codice_28命令在它们和主要栈之间压入和弹出数值。存储栈顶元素到寄存器中并把这个元素留在栈顶,需要联合使用codice_29命令。
title: 字符串.
content: 字符串是包围在codice_30和codice_31之中的字符,可以被压入栈顶和存入寄存器。使用codice_32命令从栈顶弹出字符串并执行它,使用codice_33命令从栈顶弹出并打印字符串,无尾随换行。codice_34命令可以把数值的低位字节转换成ASCII字符,或者在栈顶是字符串时把它替换为这个字符串的第一个字符。此外没有方法去建造字符串或进行字符串操纵。  codice_35字符开始一个注释直到此行结束。
title: 宏.
content: 通过允许寄存器和栈项目像数值一样存储字符串,从而实现了宏。一个字符串可以被打印,也可以被执行,就是说作为dc命令的序列而传递。例如可以把一个宏“加1并接着乘以2”存储到一个寄存器codice_36中: <syntaxhighlight> </syntaxhighlight> 通过使用codice_32命令弹出栈顶的字符串并执行之,如下这样使用存储的宏: <syntaxhighlight> </syntaxhighlight> codice_38命令从栈顶弹出一个值作为退出宏的层数,比如codice_39命令退出2层宏,它永不导致退出dc。codice_2命令退出2层宏,如果宏少于2层则退出dc。
title: 条件.
content: 最后提供了有条件执行宏的机制。命令codice_41将从栈顶弹出两个值,如果二者相等,则执行存储在寄存器codice_10中的宏。如下命令序列将在原栈顶元素等于5的条件下打印字符串codice_43。 <syntaxhighlight> [[equal]p] sm d 5 =m </syntaxhighlight>  这里使用了codice_9命令保留原栈顶元素。其他条件有codice_45、codice_46、codice_47、codice_48、codice_49,如果栈顶元素分别大于、不大于(小于等于)、小于、不小于(大于等于)、不等于仅次于栈顶的元素,则执行指定宏。
title: 迭代.
content: 通过定义有条件的调用自身的[[递归]]宏,[[迭代]]也是可行的。一个简单的对栈顶元素的[[阶乘]][[子程序|过程]]: <syntaxhighlight> </syntaxhighlight> 可实现为: <syntaxhighlight> </syntaxhighlight> 这里宏中的第一个codice_9命令相当于分配了一个局部变量。
title: 例子.
content: [[Unix]] [[Version 7 Unix|V7]]手册页举出的编程实例为打印[[阶乘]]n!的前10个值:  $ dc [la1+dsa*pla10>y]sy 0sa1 lyx 1 2 6 24 120 720 5040 40320 362880 3628800  这个程序实现了[[For循环]],将作为循环体的宏codice_51存储在寄存器codice_52中;把寄存器codice_34作为[[循环计数器]],设其初始值为codice_4,将0!的值codice_55压入栈顶;从寄存器codice_52中取出宏并执行之。宏中的codice_57将计数器codice_34的数值加codice_55,并将这个值留在栈顶;随后codice_60从栈中弹出两个元素进行乘法并把结果压入栈中,打印这个结果;随后codice_61将计数器codice_34的数值和数值codice_63压入栈中,判断位于栈顶的codice_63是否大于计数器的数值,即计数器的数值是否小于codice_63,弹出二者并在判断成立的条件下再次执行存储在寄存器codice_52中的宏。计数器codice_34的数值从codice_4增加到codice_63,宏一共被执行了codice_63次。
title: 外部链接.
content: [[Category:面向堆栈编程语言]] [[Category:跨平台软件]] [[Category:Unix软件]] [[Category:软件计算器]] [[Category:自由数学软件]] [[Category:数值分析语言]]

Summary: dc(desk calculator:桌面计算器)是采用逆波兰表示法的跨平台计算器,它支持任意精度算术。它是最老的Unix实用工具,先于C语言的发明。像那个年代的其他实用工具一样,它有着一组强力的特征和简洁的语法。传统上,采用中缀表示法的bc计算器程序是在dc之上实现的。

Dc (programovací jazyk): Manuálová stránka programu GNU dc říká: 'Dc je kalkulátor s reverzní polskou notací a neomezenou aritmetickou přesností'. Je jednou z nejstarších Unixových utilit a předchází dokonce vzniku programovacího jazyka C. Stejně jako jiné utility té doby se vyznačuje mocnými vlastnostmi, také však extrémně strohou syntaxí. Tradičně, na základě dc byl vytvořen uživatelsky příjemnější kalkulační program bc (s infixovou notací), ačkoli většina jeho současných implementací už není s dc nijak spojena.