讓我們用中文編程(二)之C++篇 - 自己做中文編程語言,你也行
作者 : Dancefire (Dancefire [at] gmail)
日期 : 2005年11月11日
由於CSDN的Blog好像對錶格支持不好,我貼了幾次,都導致了重複的內容。所以,爲了能夠貼到這裏,我把表格都改變了,所以,推薦大家訪問沒有改過格式的連接:http://www.dancefire.org/Project/SinoProgram/
引言
上回書說到,用C#來進行中文編程,最後的主程序上很是有趣,沒看過的客官,可以看看第一篇《讓我們用中文編程》。看到有些客官,在後面說到,如果連那些關鍵字也能夠中文化就好了。當時心中無奈,唉,誰叫C#不支持#define來替換關鍵字呢?在這風雲變幻的年代,每一分鐘都有奇蹟的發生,曾經的“不可能”,很有可能就變成了“想當然”。當初的無奈,現在還是無奈麼?請看下文。
-
中文編程的神化
隨着11月7日,微軟Visual C++ 2005的發佈,我們關注到,VC8.0中增加了大量新的特性,包括最重要的,引入了C++/CLI,可以說是給C/C++語言歷史上掀起了新的一頁。作爲一個方言的出現C++/CLI會有什麼樣的作爲,卻是值得大家拭目以待,是功是過,由歷史來評說。但是我們也注意到,VC8.0引入了一個非常有趣的支持,VC8.0開始支持Unicode的源代碼了。如同C#和Java一樣。如今,我們要寫C++程序,已經完全允許在代碼中出現Unicode編碼的變量名、函數名、類名等等,並且#define也支持Unicode替換了。
雖然是個小變化,但是,中文編程的世界一下就變了。這使我立刻就想到,國內有些公司,在致力於炒作中文編程,細看他們的語言,無非是對現有語言把關鍵字替換成了中文而已,其他的改進太小了。有的是把Forth給用中文關鍵字包裝了一下,就推出來的;還有的是把C語言用中文的關鍵字替換一下就推出來的。這樣的語言,真的是自己的麼?這樣的語言真的有價值麼?“決定一切的不是語言而是思想!”,這是已經人人共知的思想,國內的某些專家和公司竟然還在爲這種“僞中文”編程而津津樂道,甚至有些獲得了國家項目的資助。如果真的僅僅是用中文關鍵字來進行編程就可以改變我們國家的IT面貌的話,那大可不必投資數十萬甚至上百萬來做,用我下面的一個頭文件就夠了。
關鍵字使用中文,很簡單的技術;實現一個別人已經發明的語言,也不是什麼太複雜的事情(當然如果做一個100%兼容的C++這樣的複雜語言的編譯器還是具有相當的難度的)。真正難的應該是理解這種語言的創新思想,發現或者創造一種方法,以解決現有語言在程序設計上的存在的種種問題,這樣更新或者創造出來的纔是真正有用的經典之作。不用細說,大家都知道,C、C++、Java、C#、Ruby、Python的誕生都分別解決了什麼難題。他們用漂亮的辦法解決了一直困擾程序員的問題,他們就成爲了經典。而國內那些做中文編程的公司的產品呢?呵呵,也許僅僅是茶餘飯後而笑柄而已。
不好意思,一時感慨頗多,囉裏囉唆了那麼多廢話。下面言歸正傳。。。
- 沒有什麼不可以
再細說之前,需要說一下編譯器的事情。
目前我不知道還有哪個編譯器能夠對Unicode有良好的支持,所以,目前只有Visual C++ 2005才能夠編譯下面的代碼,但是很幸運,原本打算賣US$49的Visual C++ 2005 Express,從現在開始,一年內是免費的,而且微軟沒有一年以後的收費計劃,所以也許我們可以一直合法的用下去,呵呵。大家可以從微軟網站直接下載,需要下載的訪問下面的連接:
http://msdn.microsoft.com/vstudio/express/visualc/
下面的代碼都可以在Visual C++ 2005 Express 版上編譯通過。
好了,真的言歸正傳了。我用了一系列的#define宏和typedef,作了中文和英文關鍵字的替換。比如:
typedef int 整型;
typedef char 字符型;
#define 如果 if
#define 否則 else
#define 返回 return
#define 常量 const
#define 標準輸出 std::cout
#define 行結束 std::endl
#define 標準輸入 std::cin
#define 字符串 std::string
#define 主程序 main
經過這樣處理後我們就可以寫出一個最簡單的中文程序:
整型 主程序( 整型 參數數量, 常量 字符型** 參數列表 )
{
字符串 路人甲;
整型 年齡;
標準輸出 << "請輸入姓名:" << 行結束;
標準輸入 >> 路人甲;
標準輸出 << "請輸入年齡:" << 行結束;
標準輸入 >> 年齡;
如果(年齡 > 18){
標準輸出 << 路人甲 << "先生/女士,您好!祝您今天工作愉快哦。" << 行結束;
}否則{
標準輸出 << 路人甲 << "小朋友,您好!祝你今天玩得開心。" << 行結束;
}
返回 0;
}
程序很簡單,執行後,詢問你的姓名和年齡,如果你大於18歲呢,它就要對你說“Dancefire先生/女士,您好!祝您今天工作愉快哦。”,如果還不到18歲呢,就會說“Dancefire小朋友,您好!祝你今天玩得開心。”
這個程序似乎不夠有趣。那麼我再來一個有趣一些的,用到了面向對象的繼承的概念,新瓶裝舊酒了,前一篇文章中提到的,生物圈的例子,(既然是中文嘛,就來點中國文化特色,呵呵),
哦,多說一句,下面的程序一共由3個文件組成,其中2個是頭文件,另外一個是源文件。三個文件都可以從我的網站下載:
http://www.dancefire.org/file/SinoCPP.zip
如果大家想自己寫個中文的類玩玩,只需要#include第一個Sino.h就可以了。我已經在裏面替換了大量的關鍵字,玩玩夠了,如果還想替換其他關鍵字,你們自己加進去就行了,需要注意的是,這幾個文件都是受GPL協議保護的,簡單而言就是,大家可以隨便改,只要繼續保持開放就行了。
下面的是主程序:
//
// 作者: Dancefire (Dancefire [at] gmail)
// 日期: 公曆 二零零五年十一月十一日
// 農曆 乙酉年 丁亥月 己亥日 巳時
// 宜 解除 修飾垣牆 冠笄 出行 餘事勿取
// 忌 開市 動土 破土 嫁娶 安葬
// 項目: 中文C++編程測試
// 版本: 甲子
//
#include <vector>
#include <iostream>
#include <string>
#include "sino.h"
#include "SinoTest.h"
使用 名字空間 標準庫;
整型 主程序( 整型 參數數量, 常量 字符型** 參數列表 )
{
標準輸出 << "世界你好!" << 行結束 << 行結束;
使用 名字空間 中文編程;
矢量<生物*> 動物們;
動物們.排到後面( 新建 鳥());
動物們.排到後面( 新建 魚());
動物們.排到後面( 新建 馬());
動物們.排到後面( 新建 動物());
動物們.排到後面( 新建 生物());
循環(無符號整型 甲 = 0 ; 甲 < 動物們.多少() ; ++甲)
{
生物* 小傢伙 = 動物們[甲];
小傢伙->自我介紹();
動物* 小動物 = 動態轉型<動物*>(小傢伙);
如果( 小動物 ){
小動物->移動();
}
標準輸出 << 行結束;
}
返回 0;
}
主程序很簡單,先建立了一個動物們的容器,然後一個一個新的動物加入到這個容器(隊列)中了。(當然嚴格來說,應該是生物們,但是聽起來好怪,就叫動物們好了。)這些動物們排好隊後,開始一個接着一個的自我介紹,如果是動物呢,就動一動,如果不是動物就算了。
執行的結果是這樣的:
世界你好!
我屬於動物, 我是一隻可愛的鳥
這隻鳥在自由自在的飛翔
我屬於動物, 我是一條可愛的魚
這條魚在自由自在的游來游去
我屬於動物, 我是一匹可愛的馬
這匹馬在自由自在的奔跑
我屬於生物, 我是一隻可愛的動物
這隻動物在自由自在的移動
我是...咦?我是什麼?我也不知道我是什麼,難道我是一個外星的生物
大家可以在程序中感受到C++的OO的概念。這裏面有5個類,動物類繼承了生物類能夠自我介紹的能力,鳥、魚、馬 繼承了動物類能夠移動的能力,而他們在繼承自我介紹的時候,用自己的方式替代(重寫)了原始生物的自我介紹方式,此處自然用到了虛函數,既然是表現繼承,怎麼能沒了虛函數呢,是吧。在判斷是否是動物的時候,用到了C++標準的動態轉型,這是在運行期,而不是編譯期,進行轉型的。類的定義在頭文件SinoTest.h中,完整的這個頭文件如下:
// 作者: Dancefire (Dancefire [at] gmail)
// 日期: 公曆 二零零五年十一月十一日
// 農曆 乙酉年 丁亥月 己亥日 巳時
// 宜 解除 修飾垣牆 冠笄 出行 餘事勿取
// 忌 開市 動土 破土 嫁娶 安葬
// 項目: 中文C++編程測試
// 版本: 甲子
//
名字空間 中文編程
{
// 生物類
類 生物
{
公有:
生物() {
類別 = "生物";
祖先的類別 = "遊離態";
}
虛 ~生物(){}
虛 字符串 我的類別()
{
返回 類別;
}
虛 字符串 我祖先的類別()
{
返回 祖先的類別;
}
虛 無值 自我介紹()
{
標準輸出 << "我是...咦?我是什麼?我也不知道我是什麼,難道我是一個外星的" << 我的類別() << 行結束;
}
受保護的:
字符串 類別;
字符串 祖先的類別;
};
// 動物類,動物當然是生物啦
類 動物 : 公有 生物
{
公有:
動物() {
移動方式 = "移動";
量詞 = "只";
類別 = "動物";
祖先的類別 = "生物";
}
虛 無值 移動(){
標準輸出 << "這" << 量詞 << 我的類別() << "在自由自在的" << 移動方式 << 行結束;
}
虛 無值 自我介紹() {
標準輸出 << "我屬於" << 我祖先的類別() << ", 我是一" << 量詞 << "可愛的" << 我的類別() << 行結束;
}
受保護的:
字符串 移動方式;
字符串 量詞;
};
// 鳥類,鳥是動物咯。
類 鳥 : 公有 動物
{
公有:
鳥(){
移動方式 = "飛翔";
量詞 = "只";
類別 = "鳥";
祖先的類別 = "動物";
}
};
// 魚也是動物咯
類 魚 : 公有 動物
{
公有:
魚(){
移動方式 = "游來游去";
量詞 = "條";
類別 = "魚";
祖先的類別 = "動物";
}
};
// 馬也是動物
類 馬 : 公有 動物
{
公有:
馬()
{
移動方式 = "奔跑";
量詞 = "匹";
類別 = "馬";
祖先的類別 = "動物";
}
};
}
至於Sino.h的內容,我就只列一部分好了,大家需要的,直接從上面的連接下載吧,因爲太長了,而且都是一樣的宏定義,非常簡單,沒有什麼有趣的事情。
// 作者: Dancefire (Dancefire [at] gmail)
// 日期: 公曆 二零零五年十一月十一日
// 農曆 乙酉年 丁亥月 己亥日 巳時
// 宜 解除 修飾垣牆 冠笄 出行 餘事勿取
// 忌 開市 動土 破土 嫁娶 安葬
// 項目: 中文C++編程 頭文件
// 版本: 甲子
//
// 變量
typedef bool 布爾;
typedef char 字符型;
typedef short 短整型;
typedef int 整型;
typedef unsigned char 無符號字符型;
typedef unsigned short 無符號短整型;
typedef unsigned int 無符號整型;
typedef unsigned long 無符號長整型;
typedef long 長整型;
typedef float 浮點型;
typedef double 雙精度型;
typedef std::string 字符串;
// 常量
const bool 真 = true;
const bool 假 = false;
// 關鍵字
#define 抽象 abstract
#define 內嵌彙編 __asm
#define 中斷 break
#define 得 case // ???
#define 捕獲 catch
#define 類 class
#define 常量 const
#define 常量轉型 const_cast
#define 繼續 continue
#define 默認 default
#define 委託 delegate
#define 刪除 delete
#define 不推薦 deprecated
#define 動態鏈接庫導出 dllexport
#define 動態鏈接庫導入 dllimport
#define 做 do
#define 動態轉型 dynamic_cast
#define 否則 else
哦,唯一的問題是,我不知道switch和case如何翻譯。目前我的翻譯是,判斷和得。所以,如果用到switch的話,代碼看起來可能比較奇怪:
判斷( 甲喫的餃子盤數 ){
得 1:
標準輸出 << "竟然甲才吃了1盤餃子,不正常" << 行結束;
中斷;
得 2:
標準輸出 << "甲一個人就吃了2盤餃子,夠實力" << 行結束;
中斷;
得 3:
標準輸出 << "沒搞錯吧?甲吃了3盤餃子,不會一天沒喫飯,就等這頓了吧??" << 行結束;
中斷;
默認:
標準輸出 << "無語了~~,我都不知道甲他吃了幾盤了" << 行結束;
中斷;
}
- 自己做一箇中文編程語言,你也行
自己做一箇中文編程語言?沒有開玩笑吧?是的,是沒有開玩笑。那些大公司所謂的什麼漢語編程語言,相當一部分,就是對某種語言的模擬,只不過關鍵字用中文替代了而已,有模擬VB的,有模擬C的,還有模擬Forth的。既然是這樣也較“中文編程語言”的話,呵呵,那好,我們也做一個好了,比他們更省人力,更簡單。
通過剛纔的例子,大家已經看到了,我基本上使用純中文寫了一個程序,我相信有C++爲依託,這個肯定是最強大的,能夠用中文寫程序的語言了,哈哈~~(真不要臉,牛什麼牛,那些強大的功能是C++給你提供的,你可啥都沒做,就是換了換關鍵字而已嘛。汗~~~)。
想自己創造一個有自己個性的“中文編程語言”,大家從我的網站下載Sino.h這個文件:
http://www.dancefire.org/file/SinoCPP.zip
大家可以根據自己的想法,隨意的改動關鍵字的中文,有什麼好的想法,也可以給我回覆在這裏。給大家舉幾個簡單的例子。大家可以把Sino.h中的public對應的中文,替換成“大家的”,private對應成“我的”,protected對應成“我們家的”,friend可以對應成“哥們兒”,int可以對應成“小樣兒”,std::string對應成“條幅”,std::cout對應成“嚷嚷”,std::cin對應成“告訴”。std::endl對應成“行了您吶”,main對應成“龍門客棧”,if對應成“若”,else對應成“否”,return對應成“回報”等等。哈哈,結果這個設計的“中文編程語言”可能就變成下面的樣子了:
小樣兒 龍門客棧()
{
條幅 英雄;
小樣兒 年方几何;
嚷嚷 << "客官貴姓啊?";
告訴 >> 英雄;
嚷嚷 << "哦,兄臺,年方几何啊?";
告訴 >> 年方几何;
若(年方几何 > 16){
嚷嚷 << 英雄 << ",大英雄,久仰久仰,您請樓上落座。" << 行了您吶;
}否{
嚷嚷 << 英雄 << "小英雄,早有所聞,今日得見果然氣度不凡,裏面請。" << 行了您吶;
}
回報 0;
}
這段程序和第一個程序的意思,實際上是一樣的,但是顯得更有趣味,輸出大體如下:
客官貴姓啊?喬峯
哦,兄臺,年方几何啊?28
喬峯,大英雄,久仰久仰,您請樓上落座。
客官貴姓啊?楊過
哦,兄臺,年方几何啊?14
楊過,小英雄,早有所聞,今日得見果然氣度不凡,裏面請。