完全用 GNU/Linux 工作【闲】】[1]

完全用 GNU/Linux 工作
理解 GNU/Linux

注:本文是清华“牛仔”王垠的“成名作”,在网上引起很大的争议。对他崇拜地五体投地者有,对他嗤之以鼻者也有,总之成了一年多以前Linux 爱好者的圈子里的一个很有意思的现象。之后他对这篇文章进行了很大的修改,已经没有了原来那种意气风发。现存的版本如白开水一般无味,请参见:http: //learn.tsinghua.edu.cn/homepage/2001315450/
尽管他原来的观点有所偏激,但我还是很欣赏他原来的风格。

“UNIX 是简单的,你不需要成为天才也能理解这种简单。”
由于GNU/Linux这个词太长,下面如果没有特别指明,“Linux”就是指“GNU/Linux”。

在这个年代,恐怕没有人需要我来介绍 Linux 是什么了吧?如果你觉得“Linux 只不过是跟 DOS 差不多的东西”,那你恐怕很久在山洞里没见天日了吧?请问问你旁边的 Linux 用户,Linux 到底是个什么地位?

那为什么我还要写一篇这样的文章?因为,我发现还有很多人不不理解 Linux 和 UNIX,虽然他们也在用它,但是他们有时会问:“为什么 Linux 不能像 Windows 那样 ……?”,“怎么Redhat Linux不能 mount NTFS 分区!”,“Linux下用什么整理硬盘?”,“什么时候OpenOffice才能完全兼容Word文件啊?”,“现在还有什么Windows能干的事情 Linux干不了的?”……

他们有40G的硬盘,却只为 Linux 分配了2G空间,有时还抱怨“这个东西怎么占这么多硬盘!” 似乎 Windows该占用大部分硬盘。他们把重要的数据装在Windows的分区,似乎信不过 Linux。他们总是到处寻找新奇的,好看的GUI程序,对命令行的东西一概不屑一顾。他们对Drag&Drop,菜单配置,自动升级非常感兴趣。他们如果找到一个很像 Windows 程序的 Linux 程序,一定会很高兴的说:“哈哈!Linux 也能……了!” 如果Linux在某种测试中胜过Windows,他们会高兴得跳起来。他们没有办法用Linux解决问题的时候,甚至用Wine来运行Windows程序。有时实在没办法,只好重起到 Windows,或者干脆省得麻烦,在 Windows 下装一个 VMWare 虚拟一个 Linux 玩。

你支持 Linux,你喜欢 Linux,你能从中感觉到快乐,这非常好。你现在只需要明白的是:Linux 从来就不是一个玩具,它是天才UNIX的后代。UNIX 是自晶体管发明以来最伟大的发明,它从诞生那一天开始就比 Windows 的设计出色。Linux 并不需要追赶 Windows,不需要打垮微软,它的最终目标是改变整个计算机世界,还人们自由,给人们乐趣和方便。其它UNIX很多都已经败在Linux脚下,更何况 Windows!

你如果出现了以上的情况,说明你的思想受到了 Windows 的某种潜移默化的影响和误导。你没有能够从本质上理解存在于 Linux 身上的 UNIX 思想。UNIX的设计者 Dennis Ritchie 说:“Unix is simple. It just takes a genius to understand its simplicity.” 但是我不这么认为,因为我不是一个天才,但是我却勇敢的把Windows完全删除掉,半年之后我体会到了 UNIX 的思想和好处。因为我相信这样的信念:“Windows 能办到的事 Linux 一定能办到,而且办的更好。”

这小节开头的话应该改成:“Unix 是简单的,但是在这个冲斥着 Windows 错误观念的世界,你需要信念和勇气才能理解它的简单!” 我下面就告诉你一些我理解到的东西。

微软的地位

微软的名声在欧洲和美国的大学里,特别是在计算机系里之坏,大家可能有所耳闻。我认识的 MIT,Stanford 的教授,贝尔实验室的专家,甚至一个欧洲小国的高中计算机老师都绝口不提微软的名字。在他们眼里,微软只是一个没有真技术,专靠在落后国家商业宣传和垄断经营的小公司。这个“小”并不是说它人少,钱少,而是说它先进技术少。

我上次和王益合作写了一个算法演示程序,那个算法是贝尔实验室一位科学家Steven Fortune很天才的发明,为了程序能够被身边大多数人使用,我们选择了 VC+MFC 作为平台。我在分析算法时还得到 Fortune 很热情的鼓励,寄给我一份资料,还多次回信耐心的给我讲解了很多细节。但是程序完成之后,我把样品发给 Fortune,他回信说:“对不起。我机器上没有 MFC。” 话说的很客气,但是我已经感觉到了他对 Windows 的不屑。然后我把 MFC 静态编译进程序再发给他,他就没有再回信了。他显然不是瞧不起我,而是确实有难处。

你能感觉到这位科学家对微软和 Windows 是什么态度了吧?不是反感,而是他心里根本没有 Windows 这个东西!微软在高科技领域没有发展,那么它怎么生存呢?到发展中国家去发展一下,他们的人民还对电脑一无所知,我说不定甚至可以打入大学的计算机系呢。我送他们软件,我捐钱盖大楼,我出钱找图灵奖获得者来演讲,让他们觉得我们都是科学家!

好了,现在全国的大学包括清华,几乎所有人机器必装盗版 Win2000,Office XP,学校的选课系统是非IE不能正确浏览,论文用 Word 编辑,演示用ppt做,email 的通知附件是 doc 文件,你不用 Word 打不开,连 863 项目都用 VC 写程序了。我很久以前就看到一份报纸说,“微软为什么不严厉打击盗版?” 这篇文章说,微软非但不打击中国的盗版行为,而且有放任之趋势。放长线吊大鱼,“以后我要你们加倍的来还我!” 确实如此,它的目的快实现了。

Windows 笼罩下的中国计算机教育

说句丢脸的话,比尔盖茨很久以前是我的偶像…… //blush

在中国,比尔盖茨被很多人奉为神圣,“少年电脑天才”,甚至有的人提到他的名字就做出“抱拳对天”的姿势。很多人谈到微软的“新技术”,“高科技” 都是眉飞色舞。各种“VC编程圣经”,“深入了解 Visual C++”之类的书,在开头几页都会出现非常肉麻的字眼,“在那团团的混沌中,一个开天辟地的精灵,Windows 1.0,诞生了……”

微软的软件被这么多人盗用,那么人们是怎样使用这些盗版程序的呢?先看看电脑培训班,教的都是一些 DOS 命令,打字,Windows 基本操作,Word 文档处理,PowerPoint,高级班可能有 Excel,Access…… 参加各种微软认证考试,MCSE,MSDE 的人络绎不绝。考试辅导班都贴出了“280元,考过为止”之类的字样。考试参考资料更是昂贵,有些电脑书店整整两书架都是“Microsoft Press”的东西。我有个同学参加认证考试,每门考试都要200多元。而且你一次考不过可以再考,又要交钱。他后来还津津乐道跟我说,看我,花了 XXXX(一个四位数)元考过了微软认证,得到一张比尔盖茨亲笔签名的证书和价值6000元的 Windows XP 内部发行版。

“电脑要从娃娃抓起”,我们再来看看娃娃们学的是什么。大部分家长给孩子买了电脑之后,他们首先就会装一个盗版的 Windows,然后买来盗版的游戏开始玩。如果哪个孩子会用 Delphi 编程序,那可不得了。报社记者,电视台争相报导,说,某某学校的初中生某某,在别人都还在玩电脑游戏这种“初级阶段”的时候就已经用 Delphi 写程序了。镜头还瞄准了他显示器上面的像框中的比尔盖茨头像!

我刚进入大学计算机系时还不懂得什么是操作系统,因为我以前只用过“中华学习机”。看到新入学的同学们各个谈论的都是 “Windows 95”,“VC”…… 我简直觉得我落后了好几十年一样,整个一土人,根本跟他们答不上话。好不容易找到一个比较熟的同学问了一下:“你们天天谈论的瘟95是什么啊?”答: “win95就是一个操作系统,跟DOS是一类。”“朵死是什么?” “你连DOS都不知道是什么?别在计算机系混了。” 学校上课当然不讲VC编程之类的东西,但是上 Pascal 的老师有一次就说:“嗨,我们学校真是落后。现在别人都用 C, C++,甚至 VC 了,我们还在讲 Pascal。不知道什么时候才能有VC课啊。你们出去也是要用VC的,只好自学了。” 于是,有些同学很多时候上课都捧着一本很重的“Windows 编程大全”之类的书,根本没有听课。吃饭时就念念有词的跟我说,“代码的优化是无止境的”,“匈牙利命名法真是伟大的发明” …… 这就是中国很多大学计算机系的情况。

感觉到无知了?这不是偶然的,而是微软长久以来埋下的伏笔。它要让无知的大家都把它奉为神圣,它要让支持UNIX,Xwindow的人一旦说 UNIX 好,Xwindow 好的时候,都被一群人围着说教:“这个 Windows 也能做到”,“你对 Windows 有偏见”,“微软才是主流啊”,“你敢瞧不起 win2k?”,“.NET 就是世界潮流”,“微软的毕竟是新技术”,“有钱就是有技术”…… 甚至在一番论战比较后败下来还是要说:“Windows 性能差点,但是易用性强”,“Windows 是老百姓用的,要求别那么高”,“微软那么有钱,以后想超过 UNIX 还不容易吗?”……

发达国家的计算机教育

我前段时间在 USENET 发文问有关 Scheme 语言的问题时,认识了一位丹麦人。他解决了我所有的问题,并且建议我阅读一些很“深奥”的有关程序语言语法,文法的书,他告诉我很多网站可以学习 LISP,Scheme,人工智能,算法。他叫我看 Jonathan Rees 的论文 "Syntactic Closures"。他还打包给我寄过来一份 MIT 的 "How to Design Programs"。他说他在自己的 PC 机上装的是 Linux,他用 Emacs 编辑,运行 Scheme 程序。他对 Emacs 的了解和爱好真是使人惊讶。他大学本科毕业时做的毕业设计是一个 Scheme 解释器。这对于我来说是望尘末及了。

他是那么的不厌其烦,我的每一个问题他都详细的回答。我有时都觉得过于详细了,怎么这么耐心啊?我觉得他似乎是我的高中老师。他是什么样的人呢?我好奇的打听了他的情况。原来,她是丹麦一所普通高中的计算机老师,而且是个女老师!

她说她在高中里讲授程序设计和算法,计算机语言文法。她说用 Scheme,她的学生不用再为内存泄漏等程序语言本身的问题而烦恼,而专注于问题和算法本身。有利于培养学生解决问题的能力,特别是用计算机解决数学问题的能力。

天哪!为什么欧洲出现那么多数学家,几何学家?你看看别人重视的是什么!我们的计算机教育如果继续这样下去,只会沿着弯路越走越远!

微软和它的朋友们的如意算盘

下面来看看微软的收入是怎么来的。首先,Windows 98系列操作系统,一个就是 100 多美元,每次升级又是几乎同样的价钱。Windows NT 还要贵几倍,而且有用户数目限制,5个用户的,10个用户的…… 以后如果要增加用户数目还要按比例付钱。这个奇怪的现象被通用汽车公司的总裁比喻为:“你买的微软牌汽车最开头只有一个座位,每加一个座位你得向汽车公司付钱,每开100英里要大修一次,每过一年要换一次引擎。”

花了如此多钱买来的操作系统就能用了吗?它竟然连压缩程序都没有提供!你装上 Windows 之后一般第一件事就是去下载一个 WinZip 吧,“只要 29 美元”。Windows 会中病毒啊,马上花 70 美元买一个 Norton AntiVirus 吧。还有黑客呢?再买一个 Norton Internet Security 好了,100 美元。系统需要优化,磁盘需要整理,买一个 Norton System Works 是你最佳的解决方案,100美元。

可是你现在还是不能干正事啊!你想要一个 Word, PowerPoint?那就买一套 Office XP 吧,一起买便宜些,9.90。

那些程序不会用啊!那些菜单怎么设置,到底有什么功能啊?看“帮助”也学不会。买本书看看吧,我推荐“Special Edition Using Microsoft Office XP”,不贵,.99。这本书里面大部分是屏幕抓图,还是买一本旧的比较划算,.85。

你如果只是当个秘书,上面的差不多还凑合了。可是你有更高的追求,你想成为 Windows 程序员。首先买一个 Visual Studio.NET 吧,要不然怎么编译程序。4.95。

为了紧跟微软动向,世界潮流,不能不注册个 MSDN 什么的吧?这个贵一点,不过物有所值啊,,799。

嗯,你现在已经是上层阶级,白领人士了。你现在可以像这样“自由”的,“安全”的生活了:

什么是 Windows 能干而 Linux 干不了的事情?

“Windows 能干而 Linux 干不了的事情,那就是不需要干的事情。”

有个朋友看我半年没有用 Windows,有时就会问我:“你只用 Linux,有没有发现有些 Windows 能处理的事情 Linux 干不了?”

我回答说:“Windows 能干而 Linux 干不了的事情,那就是不需要干的事情。”
Windows 能做的有益的事情 Linux 都能做

Windows 下的某些功能确实是我们需要的,那么 Linux 的开发者们和用户也需要这种功能,他们就会去实现这种功能,而且比Windows 的方式好得多。由于大多数科学家,工程师用的都是 Linux 或者某种商业 UNIX, 所以几乎所有商业的科学工程程序,比如Matlab, Mathematica, AutoCAD, Candence的,Synopsys的,Avant! 的……全都是先有 UNIX 的版本(包括Linux),然后再考虑移植给 Windows,甚至根本不移植给 Windows,因为 Windows 的机器一般没有足够的能力运行这样的程序。你不要以为只有 Windows 才有 PSpice, UNIX 的 HSpice 要好得多,而且可以运行在大型主机上。当然它们不是免费的,但是它们值那个价钱。

但是 Windows 下有些东西在 Linux 下没有很相似的,或者你找到很多类似的,但是它们每一个比起 Windows 的那个程序都要差很多,那么原因有两种可能性:

1. 有一个完全类似的程序,但是由于它乍一看不漂亮,被你忽略了。

而其它程序虽然看起来很漂亮,但是它们是一些初学编程的人写的。现在由于 Gtk+, Qt 的诞生,Linux 下开发图形界面程序极其简单,很多初中生甚至小学生都可以随手编出一些漂亮不中用的程序。如果你整天寻找这样的程序挑来挑去,永远也找不到你满意的。

我曾经也犯过这样的错误,优秀的 FVWM, lftp, Mutt, wget 都被我忽略过!当我找回它们的时候,我是那么的羞愧不已,它们现在都是我的朋友 Smile 用这些程序你可以改变它们的一切,我第一次看到 FVWM 觉得它只不过是一个有很厚很难看边框的东西。可是现在,我的同学看到 FVWM 都说:“哇!真漂亮。”

2. 有另一种完全不同的方式可以达到相同的目的,甚至更好。

很多人很关心 Open Office, Star Office, AbiWord, … 他们多么盼望有一天某一个 Linux 程序能够完全兼容的打开一个复杂的 doc 文档。但是你永远也不可能有那一天。为什么呢?因为微软为了占有市场,必定不会让其它系统的程序能够完全兼容它的文档格式!它一定会不断变化 doc 文档的内部结构,隐藏一些秘密,让其它公司的程序打开 doc 文档时总是有某种问题,从而你必需购买 Microsoft Office 和Windows。

你应该想一下,那么多的高智商的大学教授,科学家,学生,他们用的都是 Linux 或者其它类型的 UNIX,他们没有 Word 可用,怎么处理文档呢?这么多年没有一个像 Open Office 的程序出现,难道大家没有办法写文档吗?

显然不是这样。你看看那些高水平的学术杂志,论文,那些大学教授的网页,那些漂亮的PDF幻灯片,它们是什么做的?原来 UNIX 用户早就有非常方便的 troff, LaTeX, SGML 等东西可以处理文档,而且它们比起 Word 都要高明的多。Word 显然被这些大拿忽略了,以至于很久以来没有人想在 Linux 下开发一个类似 Word 的程序,除非某些公司想抢微软的饭碗。

很多人留着 Windows 在硬盘上的原因无非是为了用 Word 和 PowerPoint。你待会儿可以看看我的TeX网页,你就会知道为什么我可以完全离开 Windows.

Windows 能做的那些没用的事情 Linux 永远做不好

1. 电脑游戏

有些人说 Linux 下不能玩 Windows 下所能得到的所有游戏。的确,Linux 下虽然也有少量的游戏,比如 Quake。但是它没有 Counter Strike, 没有 Star Craft, ……

并不是说电脑游戏不该玩,但是应该适可而止。电脑是用来处理事务,帮助你学习,解决问题的工具,而不是一个玩具!整天沉迷于电脑游戏中,而不出去感觉外面的世界,你会变得越来越冷酷,越来越缺乏人情味。你与真实的世界越来越远。

你可以在 CS 里杀人,你可以在 Tomb Raider 里探险,你甚至可以在 Tony Hawk’s Pro Skaters 里滑板…… 但是 It’s not real!你虽然有很高的“反恐技巧”,但是遇到歹徒的时候,你是那么的怯懦;你虽然控制 Laura 伸手敏捷,但是你打篮球的时候怎么总是被人断球?你虽然可以轻易的在 THPS 里作出一个 "360 kickflip to hangten grind to fakie",但是你踩在自己的滑板上的时候还不会 ollie!

说回来,如果你偶尔玩一下电脑游戏未尝不可。但是世界上有远比 Windows + PC 更好的游戏方式。Sony 的 PlayStation2, SEGA 的 DreamCast, Nintendo 的 N64,Namco 的街机……每一个都比 Windows 游戏精彩,每一个都有如此高的3D性能,以至于 Pentium4, Itanium + GForce4 都无法与它们比美!

Linux 的用户们都是关心解决世界的关键问题的份子,他们哪里有时间用自己的机器来玩游戏啊?他们每天用Linux高效的做完自己的工作就到阳光下享受自然去了。要玩游戏也是玩一些类似推箱子,贪吃蛇之类的智力小游戏。所以,你知道为什么 Linux 几乎没有游戏了吧?Smile

2. “整理硬盘,优化系统”

这是一个非常有意思的话题,仅次于有关“病毒”的话题。相信很多 Windows 用户都有整理硬盘的经历。在很多 Windows 用户眼里,“硬盘用久了,会出现碎片,速度会减慢,需要一个程序来整理,整理硬盘的时候不要做其它工作”,这好像是天经地义的事情。

我也曾经津津有味的看着 Norton Defrag 一点一点的把我的硬盘排序,调整,用图形的方式显示出来,然后报告:“100% 没有碎片。你的硬盘现在已经达到最佳状态。” 我现在才发觉我那时是多么的幼稚。

Linux 和 UNIX 用户似乎从来没有“整理硬盘”这种说法呢?你觉得很奇怪吗?如果你觉得很奇怪,那说明你的思想在某种程度上被微软的垃圾程序禁锢了。你需要明白,UNIX 的大型主机很多必须是一天24小时,一年365又1/4天不停运转的,要是每个星期都要整理一次硬盘,在整理的时候几乎不能干任何事情,那是绝对行不通的!

Linux 机器根本不用整理硬盘,这就是为什么没有看到过 Linux 用户整理硬盘。Linux 的文件系统是比 Windows 的 FAT, FAT32, NTFS 高明得多的文件系统,它们不但可以对文件设置权限,实施完全的保护,而且可以“越用越整齐”,“越用碎片越少”!你应该把文件大部分放在 Linux 的分区,而不是 Windows 分区,因为它比 Windows 分区可靠得多。

还有更滑稽的事情就是有很多“Norton System Doctor”,“Windows 优化大师”,“超级兔仔注册表魔法” 之类的程序存在,而且价格昂贵。似乎一个操作系统本来应该有很多问题,需要别的厂商做程序来“优化”它,而且为了得到优化,你需要付钱!这些问题 Linux 根本就没有,所以不需要什么优化。Linux 内核本身就是高度优化的。

3. IDE

有些人在抱怨为什么 Linux 没有一个良好的 IDE 开发环境。Linux 现在已经有一些 IDE 了,但是总是有很多问题。你是不是正在寻找,正在期望 Linux 某一天可以有一个VC那样的开发环境?你有没有发现你正在进入微软给你设下的怪圈?你为什么一定要用 IDE?你说:“IDE 开发迅速,调试方便,适合大型程序……” 那说明微软的程序在你脑子里已经比较根深蒂固,你需要好好清醒一下了,看看我来告诉你。

高明的 UNIX 程序员不用 IDE,IDE 从来就是给初级 Windows 程序员用的。

你看看大型的 UNIX 程序,包括 Linux 内核,各种网络服务程序,Xwindow 程序在内,哪一个是 IDE 搞出来的?我们实验室的 EDA 程序也没有一个是 IDE 弄的,我还知道 Candence, Synopsys,Mentor 的高性能的图形界面 EDA 程序也都不是 IDE 写的。你信不信,微软的人在写 Windows 本身的时候也根本不用 IDE!

有一次某杂志采访一些出名的 Linux 内核程序员,包括 Linus 在内,没有一个人用 IDE,有的人用 VIM,有的用 Emacs,只有 Linus 说“GNU Emacs is evil”,但是其实他用的是一种跟 Emacs 有同样键绑定功能的 MicroEmacs。大家都是用编辑器编辑了程序文件,然后用 make 这样的自动工具调用 gcc 编译器完成编译工作的。

我以前也编过 Windows 程序:应用程序,驱动程序。但是我没有用 VC 的 IDE。Linux 教育了我,我会在命令行调用 CL,我知道 CL 才是 VC 的编译器。我可以在 cygwin 的 Makefile 里使用 CL。我还知道 CL 的参数都有什么用处。但是这些不是一个从一开头就用 IDE 的人能很快理解到的。

我相信: IDE is evil。我有一些用 Windows 的 IDE 写程序的朋友,他们对那套东西已经很精通了。但是我却惊奇的发现,他们竟然把编译器和汇编器的概念都分不清楚,甚至有的人连“编辑器”和“编译器”都搞混淆了!他们只知道在一个窗口里输入了代码,点击一个按钮就可以编译程序,但是这里面到底是怎么工作的,他们不知道!他们被盖在上面的窗口挡住了视线,甚至会以为那个按钮就是编译器!

他们对那些 IDE 的热键背的滚瓜烂熟,但是我却看到他们在一个函数一个函数的把别人的 ANSI 风格的代码变成 VC 的风格。想想这件事在 VIM 里有多么简单,一瞬间就可以搞定。

为什么 UNIX 程序员不用 IDE?明白了这个道理你就能体会到 UNIX 的设计思想了。首先,一个 IDE 集成了编辑器,编译器,汇编器,调试器,跟踪器…… 这个编辑器功能肯定比不上 VIM 或 Emacs,编译器比不上 GCC,汇编器比不上 as,调试器比不上 gdb, ddd, 跟踪器比不上 strace, ltrace, truss。你得到的是一套整合的低能的程序。如果你对调试器的功能不满意,你只好换用另外一套 IDE,但是这套 IDE 的热键,菜单,编辑器功能,按钮…… 跟原来那个有很大不同。你不得不花很多时间来熟悉新的环境,而不能保持原来的某些东西。

而在 UNIX 下就不一样了。你可以用你最喜欢的 VIM 编辑程序,你在 VIM 里可以调用 GNU make,make 可以调用 gcc, ld, … 实际上 make 能帮你很多忙。make 的出错信息可以被 VIM 捕获,VIM 能帮你在源程序里定位。你如果喜欢 icc, 你可以让 make 用 icc 而不是 gcc。你如果觉得 gdb 跟踪变量时比较麻烦,你可以用 ddd 来显示各种数据结构之间的关系。你还可以在 Emacs 里调用 gdb,那样就可以同步显示源代码了。而且 VIM 和 Emacs 还可以编辑很多其它东西,比如信件,LaTeX 文档,HTML,配置文件…… 你不用另外找一个什么编辑器来干这些杂活了。很多程序比如 Mutt, tin 都可以在内部使用 VIM,这样就更方便了。

Read: 709

关于如何让jre显示中文字体的方法

创建:2005-10-28 00:09:13
作者:Unlinux
来自: http://www.Unlinux.com

由于jre里font.properies默认的字体是 Turbolinux里的-tlc-song-字体,如果你没有这种字体,肯定显示的都是“口”,解决方法有2种,一个就是按照jre里的说明,按照它的方法自己添加字体,但是这个难度比较大,需要用它提供的脚本,但是对于我们这些不是很了解java程序的菜鸟来说,这个方法显然有点难度。于是,我就想,既然我自己没有办法生成字体目录,我就改我原来的fonts.dir,让它支持这种-tlc-song-字体,同时保持原来的字体-misc- simsun-。更改的方法有很多种,我的方法不一定最好,也不一定是最简单,如果那个兄弟有更好的方法,可以写出来。
1> 新生成一个fonts.dir;
2> 在原来的fonts.dir里增加新的字体定义。
我以前一种为例子,具体方法如下:
1.在/usr/X11R6/lib/X11/fonts/trutype/下建立一个新的目录ttf-zh(目录名随便你起),然后将simsun.ttf,tahoma字体拷贝至这个新建立的目录。
2.将simsun.ttf改名为tlc_song.ttf,将tahoma.ttf改为tlc_song_ascii.ttf。
3.生成fonts.dir文件:
132
tlc_song_ascii.ttf -tlc-song-medium-r-normal–0-0-0-0-p-0-iso8859-1
tlc_song.ttf -tlc-song-medium-r-normal–0-0-0-0-c-0-iso10646-1
tlc_song.ttf -tlc-song-medium-r-normal–0-0-0-0-c-0-gbk-0
tlc_song.ttf -tlc-song-medium-r-normal–0-0-0-0-c-0-gb2312.1980-0
tlc_song.ttf -tlc-song-medium-r-normal–0-0-0-0-c-0-gb18030.2000-1
tlc_song.ttf -tlc-song-medium-r-normal–0-0-0-0-c-0-gb18030.2000-0
tlc_song.ttf -tlc-song-medium-r-normal–0-0-0-0-c-0-gb18030-0
tlc_song.ttf -tlc-song-medium-r-normal–0-0-0-0-c-0-big5.eten-0
tlc_song.ttf -tlc-song-medium-r-normal–0-0-0-0-c-0-big5.et-0
tlc_song.ttf -tlc-song-medium-r-normal–0-0-0-0-c-0-big5-0
ai=0.3:tlc_song_ascii.ttf -tlc-song-medium-i-normal–0-0-0-0-p-0-iso8859-1
ai=0.3:tlc_song.ttf -tlc-song-medium-i-normal–0-0-0-0-c-0-iso10646-1
ai=0.3:tlc_song.ttf -tlc-song-medium-i-normal–0-0-0-0-c-0-gbk-0
ai=0.3:tlc_song.ttf -tlc-song-medium-i-normal–0-0-0-0-c-0-gb2312.1980-0
ai=0.3:tlc_song.ttf -tlc-song-medium-i-normal–0-0-0-0-c-0-gb18030.2000-1
ai=0.3:tlc_song.ttf -tlc-song-medium-i-normal–0-0-0-0-c-0-gb18030.2000-0
ai=0.3:tlc_song.ttf -tlc-song-medium-i-normal–0-0-0-0-c-0-gb18030-0
ai=0.3:tlc_song.ttf -tlc-song-medium-i-normal–0-0-0-0-c-0-big5.eten-0
ai=0.3:tlc_song.ttf -tlc-song-medium-i-normal–0-0-0-0-c-0-big5.et-0
ai=0.3:tlc_song.ttf -tlc-song-medium-i-normal–0-0-0-0-c-0-big5-0
ds=y:tlc_song_ascii.ttf -tlc-song-bold-r-normal–0-0-0-0-p-0-iso8859-1
ds=y:tlc_song.ttf -tlc-song-bold-r-normal–0-0-0-0-c-0-iso10646-1
ds=y:tlc_song.ttf -tlc-song-bold-r-normal–0-0-0-0-c-0-gbk-0
ds=y:tlc_song.ttf -tlc-song-bold-r-normal–0-0-0-0-c-0-gb2312.1980-0
ds=y:tlc_song.ttf -tlc-song-bold-r-normal–0-0-0-0-c-0-gb18030.2000-1
ds=y:tlc_song.ttf -tlc-song-bold-r-normal–0-0-0-0-c-0-gb18030.2000-0
ds=y:tlc_song.ttf -tlc-song-bold-r-normal–0-0-0-0-c-0-gb18030-0
ds=y:tlc_song.ttf -tlc-song-bold-r-normal–0-0-0-0-c-0-big5.eten-0
ds=y:tlc_song.ttf -tlc-song-bold-r-normal–0-0-0-0-c-0-big5.et-0
ds=y:tlc_song.ttf -tlc-song-bold-r-normal–0-0-0-0-c-0-big5-0
ai=0.3:ds=y:tlc_song_ascii.ttf -tlc-song-bold-i-normal–0-0-0-0-p-0-iso8859-1
ai=0.3:ds=y:tlc_song.ttf -tlc-song-bold-i-normal–0-0-0-0-c-0-iso10646-1
ai=0.3:ds=y:tlc_song.ttf -tlc-song-bold-i-normal–0-0-0-0-c-0-gbk-0
ai=0.3:ds=y:tlc_song.ttf -tlc-song-bold-i-normal–0-0-0-0-c-0-gb2312.1980-0
ai=0.3:ds=y:tlc_song.ttf -tlc-song-bold-i-normal–0-0-0-0-c-0-gb18030.2000-1
ai=0.3:ds=y:tlc_song.ttf -tlc-song-bold-i-normal–0-0-0-0-c-0-gb18030.2000-0
ai=0.3:ds=y:tlc_song.ttf -tlc-song-bold-i-normal–0-0-0-0-c-0-gb18030-0
ai=0.3:ds=y:tlc_song.ttf -tlc-song-bold-i-normal–0-0-0-0-c-0-big5.eten-0
ai=0.3:ds=y:tlc_song.ttf -tlc-song-bold-i-normal–0-0-0-0-c-0-big5.et-0
ai=0.3:ds=y:tlc_song.ttf -tlc-song-bold-i-normal–0-0-0-0-c-0-big5-0
tlc_song_ascii.ttf -tlc-ming-medium-r-normal–0-0-0-0-p-0-iso8859-1
tlc_song.ttf -tlc-ming-medium-r-normal–0-0-0-0-c-0-big5.eten-0
tlc_song.ttf -tlc-ming-medium-r-normal–0-0-0-0-c-0-big5.et-0
tlc_song.ttf -tlc-ming-medium-r-normal–0-0-0-0-c-0-big5-0
ai=0.3:tlc_song_ascii.ttf -tlc-ming-medium-i-normal–0-0-0-0-p-0-iso8859-1
ai=0.3:tlc_song.ttf -tlc-ming-medium-i-normal–0-0-0-0-c-0-big5.eten-0
ai=0.3:tlc_song.ttf -tlc-ming-medium-i-normal–0-0-0-0-c-0-big5.et-0
ai=0.3:tlc_song.ttf -tlc-ming-medium-i-normal–0-0-0-0-c-0-big5-0
ds=y:tlc_song_ascii.ttf -tlc-ming-bold-r-normal–0-0-0-0-p-0-iso8859-1
ds=y:tlc_song.ttf -tlc-ming-bold-r-normal–0-0-0-0-c-0-big5.eten-0
ds=y:tlc_song.ttf -tlc-ming-bold-r-normal–0-0-0-0-c-0-big5.et-0
ds=y:tlc_song.ttf -tlc-ming-bold-r-normal–0-0-0-0-c-0-big5-0
ai=0.3:ds=y:tlc_song_ascii.ttf -tlc-ming-bold-i-normal–0-0-0-0-p-0-iso8859-1
ai=0.3:ds=y:tlc_song.ttf -tlc-ming-bold-i-normal–0-0-0-0-c-0-big5.eten-0
ai=0.3:ds=y:tlc_song.ttf -tlc-ming-bold-i-normal–0-0-0-0-c-0-big5.et-0
ai=0.3:ds=y:tlc_song.ttf -tlc-ming-bold-i-normal–0-0-0-0-c-0-big5-0
tlc_song.ttf -tlc-mincho-medium-r-normal–0-0-0-0-c-0-jisx0212.1990-0
tlc_song.ttf -tlc-mincho-medium-r-normal–0-0-0-0-c-0-jisx0208.1990-0
tlc_song.ttf -tlc-mincho-medium-r-normal–0-0-0-0-c-0-jisx0208.1983-0
tlc_song.ttf -tlc-mincho-medium-r-normal–0-0-0-0-c-0-jisx0201.1976-0
tlc_song_ascii.ttf -tlc-mincho-medium-r-normal–0-0-0-0-p-0-iso8859-1
ai=0.3:tlc_song.ttf -tlc-mincho-medium-i-normal–0-0-0-0-c-0-jisx0212.1990-0
ai=0.3:tlc_song.ttf -tlc-mincho-medium-i-normal–0-0-0-0-c-0-jisx0208.1990-0
ai=0.3:tlc_song.ttf -tlc-mincho-medium-i-normal–0-0-0-0-c-0-jisx0208.1983-0
ai=0.3:tlc_song.ttf -tlc-mincho-medium-i-normal–0-0-0-0-c-0-jisx0201.1976-0
ai=0.3:tlc_song_ascii.ttf -tlc-mincho-medium-i-normal–0-0-0-0-p-0-iso8859-1
ds=y:tlc_song.ttf -tlc-mincho-bold-r-normal–0-0-0-0-c-0-jisx0212.1990-0
ds=y:tlc_song.ttf -tlc-mincho-bold-r-normal–0-0-0-0-c-0-jisx0208.1990-0
ds=y:tlc_song.ttf -tlc-mincho-bold-r-normal–0-0-0-0-c-0-jisx0208.1983-0
ds=y:tlc_song.ttf -tlc-mincho-bold-r-normal–0-0-0-0-c-0-jisx0201.1976-0
ds=y:tlc_song_ascii.ttf -tlc-mincho-bold-r-normal–0-0-0-0-p-0-iso8859-1
ai=0.3:ds=y:tlc_song.ttf -tlc-mincho-bold-i-normal–0-0-0-0-c-0-jisx0212.1990-0
ai=0.3:ds=y:tlc_song.ttf -tlc-mincho-bold-i-normal–0-0-0-0-c-0-jisx0208.1990-0
ai=0.3:ds=y:tlc_song.ttf -tlc-mincho-bold-i-normal–0-0-0-0-c-0-jisx0208.1983-0
ai=0.3:ds=y:tlc_song.ttf -tlc-mincho-bold-i-normal–0-0-0-0-c-0-jisx0201.1976-0
ai=0.3:ds=y:tlc_song_ascii.ttf -tlc-mincho-bold-i-normal–0-0-0-0-p-0-iso8859-1
tlc_song_ascii.ttf -tlc-HanyiSong-medium-r-normal–0-0-0-0-p-0-iso8859-1
tlc_song.ttf -tlc-HanyiSong-medium-r-normal–0-0-0-0-c-0-iso10646-1
tlc_song.ttf -tlc-HanyiSong-medium-r-normal–0-0-0-0-c-0-gbk-0
tlc_song.ttf -tlc-HanyiSong-medium-r-normal–0-0-0-0-c-0-gb2312.1980-0
tlc_song.ttf -tlc-HanyiSong-medium-r-normal–0-0-0-0-c-0-gb18030-0
tlc_song.ttf -tlc-HanyiSong-medium-r-normal–0-0-0-0-c-0-big5-0
ai=0.3:tlc_song_ascii.ttf -tlc-HanyiSong-medium-i-normal–0-0-0-0-p-0-iso8859-1
ai=0.3:tlc_song.ttf -tlc-HanyiSong-medium-i-normal–0-0-0-0-c-0-iso10646-1
ai=0.3:tlc_song.ttf -tlc-HanyiSong-medium-i-normal–0-0-0-0-c-0-gbk-0
ai=0.3:tlc_song.ttf -tlc-HanyiSong-medium-i-normal–0-0-0-0-c-0-gb2312.1980-0
ai=0.3:tlc_song.ttf -tlc-HanyiSong-medium-i-normal–0-0-0-0-c-0-gb18030-0
ai=0.3:tlc_song.ttf -tlc-HanyiSong-medium-i-normal–0-0-0-0-c-0-big5-0
ds=y:tlc_song_ascii.ttf -tlc-HanyiSong-bold-r-normal–0-0-0-0-p-0-iso8859-1
ds=y:tlc_song.ttf -tlc-HanyiSong-bold-r-normal–0-0-0-0-c-0-iso10646-1
ds=y:tlc_song.ttf -tlc-HanyiSong-bold-r-normal–0-0-0-0-c-0-gbk-0
ds=y:tlc_song.ttf -tlc-HanyiSong-bold-r-normal–0-0-0-0-c-0-gb2312.1980-0
ds=y:tlc_song.ttf -tlc-HanyiSong-bold-r-normal–0-0-0-0-c-0-gb18030-0
ds=y:tlc_song.ttf -tlc-HanyiSong-bold-r-normal–0-0-0-0-c-0-big5-0
ai=0.3:ds=y:tlc_song_ascii.ttf -tlc-HanyiSong-bold-i-normal–0-0-0-0-p-0-iso8859-1
ai=0.3:ds=y:tlc_song.ttf -tlc-HanyiSong-bold-i-normal–0-0-0-0-c-0-iso10646-1
ai=0.3:ds=y:tlc_song.ttf -tlc-HanyiSong-bold-i-normal–0-0-0-0-c-0-gbk-0
ai=0.3:ds=y:tlc_song.ttf -tlc-HanyiSong-bold-i-normal–0-0-0-0-c-0-gb2312.1980-0
ai=0.3:ds=y:tlc_song.ttf -tlc-HanyiSong-bold-i-normal–0-0-0-0-c-0-gb18030-0
ai=0.3:ds=y:tlc_song.ttf -tlc-HanyiSong-bold-i-normal–0-0-0-0-c-0-big5-0
tlc_song_ascii.ttf -tlc-default-medium-r-normal–0-0-0-0-p-0-iso8859-1
tlc_song.ttf -tlc-default-medium-r-normal–0-0-0-0-c-0-iso10646-1
tlc_song.ttf -tlc-default-medium-r-normal–0-0-0-0-c-0-gbk-0
tlc_song.ttf -tlc-default-medium-r-normal–0-0-0-0-c-0-gb2312.1980-0
tlc_song.ttf -tlc-default-medium-r-normal–0-0-0-0-c-0-gb18030-0
tlc_song.ttf -tlc-default-medium-r-normal–0-0-0-0-c-0-big5.eten-0
tlc_song.ttf -tlc-default-medium-r-normal–0-0-0-0-c-0-big5.et-0
tlc_song.ttf -tlc-default-medium-r-normal–0-0-0-0-c-0-big5-0
ai=0.3:tlc_song_ascii.ttf -tlc-default-medium-i-normal–0-0-0-0-p-0-iso8859-1
ai=0.3:tlc_song.ttf -tlc-default-medium-i-normal–0-0-0-0-c-0-iso10646-1
ai=0.3:tlc_song.ttf -tlc-default-medium-i-normal–0-0-0-0-c-0-gbk-0
ai=0.3:tlc_song.ttf -tlc-default-medium-i-normal–0-0-0-0-c-0-gb2312.1980-0
ai=0.3:tlc_song.ttf -tlc-default-medium-i-normal–0-0-0-0-c-0-gb18030-0
ai=0.3:tlc_song.ttf -tlc-default-medium-i-normal–0-0-0-0-c-0-big5.eten-0
ai=0.3:tlc_song.ttf -tlc-default-medium-i-normal–0-0-0-0-c-0-big5.et-0
ai=0.3:tlc_song.ttf -tlc-default-medium-i-normal–0-0-0-0-c-0-big5-0
ds=y:tlc_song_ascii.ttf -tlc-default-bold-r-normal–0-0-0-0-p-0-iso8859-1
ds=y:tlc_song.ttf -tlc-default-bold-r-normal–0-0-0-0-c-0-iso10646-1
ds=y:tlc_song.ttf -tlc-default-bold-r-normal–0-0-0-0-c-0-gbk-0
ds=y:tlc_song.ttf -tlc-default-bold-r-normal–0-0-0-0-c-0-gb2312.1980-0
ds=y:tlc_song.ttf -tlc-default-bold-r-normal–0-0-0-0-c-0-gb18030-0
ds=y:tlc_song.ttf -tlc-default-bold-r-normal–0-0-0-0-c-0-big5.eten-0
ds=y:tlc_song.ttf -tlc-default-bold-r-normal–0-0-0-0-c-0-big5.et-0
ds=y:tlc_song.ttf -tlc-default-bold-r-normal–0-0-0-0-c-0-big5-0
ai=0.3:ds=y:tlc_song_ascii.ttf -tlc-default-bold-i-normal–0-0-0-0-p-0-iso8859-1
ai=0.3:ds=y:tlc_song.ttf -tlc-default-bold-i-normal–0-0-0-0-c-0-iso10646-1
ai=0.3:ds=y:tlc_song.ttf -tlc-default-bold-i-normal–0-0-0-0-c-0-gbk-0
ai=0.3:ds=y:tlc_song.ttf -tlc-default-bold-i-normal–0-0-0-0-c-0-gb2312.1980-0
ai=0.3:ds=y:tlc_song.ttf -tlc-default-bold-i-normal–0-0-0-0-c-0-gb18030-0
ai=0.3:ds=y:tlc_song.ttf -tlc-default-bold-i-normal–0-0-0-0-c-0-big5.eten-0
ai=0.3:ds=y:tlc_song.ttf -tlc-default-bold-i-normal–0-0-0-0-c-0-big5.et-0
ai=0.3:ds=y:tlc_song.ttf -tlc-default-bold-i-normal–0-0-0-0-c-0-big5-0
生成fonts.scale:cp fonts.dir fonts.scale。
4.修改/etc/X11/XF86config文件,增加字体目录FontPath "/usr/X11R6/lib/X11/fonts/truetype/ttf-zh"
5.运行SuSEconfig,如果没有什么错误提示,重新启动xwindow,你此时运行/jre/bin/ControlPanel就会见到下面的图样。

注意事项:如果你新安装了jre1.4.1_01的话,建议安装到原来系统的默认目录/usr/lib/SunJava2-1.3.1中。同时修改. /jre/lib/font.properties.zh.Turbo,将其改名为font.properties.zh。否则仍然是“口”。
至此,一切就搞定了。

尝试:如果不想新建立目录和fonts.dir,可以在原来的fonts.dir中增加上面的字体脚本,但是要将开头的数字改为x+132(这个是说明下面有多少行,必需改)。然后做2个联接,ln -s simsun.ttf tlc_song.ttf,ln -s tahoma.ttf tlc_song_ascii.ttf。然后运行SuSEconfig,重新启动xwindow。这种改动最小,只是我当时怕这样该引起原来的字体混乱,所以按照前述的方法修改。如有不对之处,还请大家指教。
转载自:http://www.unlinux.com/doc/java/20051028/5830.html

Read: 734

[转]往JRE里添加新字体

   Adding Fonts to the Java Runtime
要加一种亚洲字体进JRE,请按以下步骤进行:
1.装入字体
首先,你必须装载中文、日文、韩文或传统的中文字体(楷书、宋体等)到你的系统里面
2.复制字体进font.properties
装好了字体后,复制你感兴趣字体的descriptio到font.properties,最简捷的方法是把
font.properties.<locale>直接改名为font.properties

例如:要使用中文字体,你可以复制或者改名font.properties.zh为font.properties.
现行的WIN32 JDK提供如下font properties 文件
./lib/font.properties
./lib/font.properties.ja
./lib/font.properties.ko
./lib/font.properties.zh
./lib/font.properties.zh_TW
     
并且你可以在JRE里使用多于一种的亚洲字体,所必须做的就是编辑font.properties
文件。
例如你要加三种SERIF字体;
serif.0=Times New Roman,ANSI_CHARSET
serif.1=WingDings,SYMBOL_CHARSET,NEED_CONVERTED
serif.2=Symbol,SYMBOL_CHARSET,NEED_CONVERTED
<virtual font name>.<index number> = <platform font name>, attributes

后面有三个参数,如Times New Roman、WingDings就是字体名
第二个参数(SYMBOL_CHARSET)是相应字符集的处理接口
第三个参数是表明相应字符集不能直接同过UNICODE编码处理,需要与UNICODE间的转换器
通过以下语句设不同FONTS的转换器
fontcharset.serif.1=sun.awt.windows.CharToByteWingDings
fontcharset.serif.2=sun.awt.CharToByteSymbol

用户也可以定制自己的字体、字符集与自定义的UNICODE转换器

例如说你想增加你自己定制的字体到JAVA的serif     系列字体里去,
假设你的字体共有256个,从0到0Xff.正对应于UNICODE里的OXE000-0XEOFF。
首先你要设计你的转换类
package mypkg.converter;

import sun.io.CharToByteISO8859_1;
import sun.io.CharToByteConverter;
import sun.io.ConversionBufferFullException;

public class CharToByteMyFont extends sun.io.CharToByteISO8859_1 {

    /*
     * This method indicates the range this font covers.
     */
    public boolean canConvert(char ch) {
       if (ch >= 0xe000 && ch <= 0xe0ff) {
          return true;
       }
       return false;
    }

    /*
     * This method converts the unicode to this font index.
     */
    public int convert(char[] input, int inStart, int inEnd,
                       byte[] output, int outStart, int outEnd)
                       throws ConversionBufferFullException {
       int outIndex = outStart;
       for (int i = inStart; i < inEnd; i++) {
          char ch = input[i];
          if (ch >= 0xe000 && ch <= 0xe0ff) {
             if (outIndex >= outEnd)
             throw new ConversionBufferFullException();
             output[outIndex++] = (byte)(ch – 0xe000);
          }
       }
       return outIndex – outStart;
    }
第二步,加你自己的字体和转换器进Properties文件
你先要增加你的字体的名子进文件里,

serif.3=<your own font name>
然后定义相应的converter
fontcharset.serif.3=mypkg.converter.CharToByteMyfont

为了确定JRE能够找到你的转换器,你的application classpath 必须包含转换器的路径

以上是我看了sun里的相关文章后觉得很不错而粗略整理出来的,目的只在于把相关内容大概介绍一下,请不要见笑,最好参考英文原文
http://java.sun.com/products/jdk/1.1/docs/guide/intl/fontprop.html
或到http://java.sun.com/products/jdk/1.1/docs/guide/intl/index.html看更多的Internationalization相关资料以及samples
本人正在做多国语的网版词典,所以有在找相关资料,这是我看到的比较有用的叙述JAVA中字符集处理的文章,如果各位看到更好的java对unicode支持的资料请告知我,谢谢

Read: 757

解析C语言复杂声明

C语言所有复杂的指针声明,都是由各种声明嵌套构成的。如何解读复杂指针声明呢?右左法则是一个既著名又常用的方法。不过,右左法则其实并不是C标准里面的内容,它是从C标准的声明规定中归纳出来的方法。C标准的声明规则,是用来解决如何创建声明的,而右左法则是用来解决如何辩识一个声明的,两者可以说是相反的。右左法则的英文原文是这样说的:

The right-left rule: Start reading the declaration from the innermost parentheses, go right, and then go left. When you encounter parentheses, the direction should be reversed. Once everything in the parentheses has been parsed, jump out of it. Continue till the whole declaration has been parsed.

这段英文的翻译如下:

右左法则:首先从最里面的圆括号看起,然后往右看,再往左看。每当遇到圆括号时,就应该掉转阅读方向。一旦解析完圆括号里面所有的东西,就跳出圆括号。重复这个过程直到整个声明解析完毕。

笔者要对这个法则进行一个小小的修正,应该是从未定义的标识符开始阅读,而不是从括号读起,之所以是未定义的标识符,是因为一个声明里面可能有多个标识符,但未定义的标识符只会有一个。

现在通过一些例子来讨论右左法则的应用,先从最简单的开始,逐步加深:

int (*func)(int *p);

首先找到那个未定义的标识符,就是func,它的外面有一对圆括号,而且左边是一个*号,这说明func是一个指针,然后跳出这个圆括号,先看右边,也是一个圆括号,这说明(*func)是一个函数,而func是一个指向这类函数的指针,就是一个函数指针,这类函数具有int*类型的形参,返回值类型是 int。

int (*func)(int *p, int (*f)(int*));

func被一对括号包含,且左边有一个*号,说明func是一个指针,跳出括号,右边也有个括号,那么func是一个指向函数的指针,这类函数具有int *和int (*)(int*)这样的形参,返回值为int类型。再来看一看func的形参int (*f)(int*),类似前面的解释,f也是一个函数指针,指向的函数具有int*类型的形参,返回值为int。

int (*func[5])(int *p);

func 右边是一个[]运算符,说明func是一个具有5个元素的数组,func的左边有一个*,说明func的元素是指针,要注意这里的*不是修饰func的,而是修饰func[5]的,原因是[]运算符优先级比*高,func先跟[]结合,因此*修饰的是func[5]。跳出这个括号,看右边,也是一对圆括号,说明func数组的元素是函数类型的指针,它所指向的函数具有int*类型的形参,返回值类型为int。

int (*(*func)[5])(int *p);

func 被一个圆括号包含,左边又有一个*,那么func是一个指针,跳出括号,右边是一个[]运算符号,说明func是一个指向数组的指针,现在往左看,左边有一个*号,说明这个数组的元素是指针,再跳出括号,右边又有一个括号,说明这个数组的元素是指向函数的指针。总结一下,就是:func是一个指向数组的指针,这个数组的元素是函数指针,这些指针指向具有int*形参,返回值为int类型的函数。

int (*(*func)(int *p))[5];

func是一个函数指针,这类函数具有int*类型的形参,返回值是指向数组的指针,所指向的数组的元素是具有5个int元素的数组。

要注意有些复杂指针声明是非法的,例如:

int func(void) [5];

func是一个返回值为具有5个int元素的数组的函数。但C语言的函数返回值不能为数组,这是因为如果允许函数返回值为数组,那么接收这个数组的内容的东西,也必须是一个数组,但C语言的数组名是一个右值,它不能作为左值来接收另一个数组,因此函数返回值不能为数组。

int func[5](void);

func是一个具有5个元素的数组,这个数组的元素都是函数。这也是非法的,因为数组的元素除了类型必须一样外,每个元素所占用的内存空间也必须相同,显然函数是无法达到这个要求的,即使函数的类型一样,但函数所占用的空间通常是不相同的。

作为练习,下面列几个复杂指针声明给读者自己来解析,答案放在第十章里。

int (*(*func)[5][6])[7][8];

int (*(*(*func)(int *))[5])(int *);

int (*(*func[7][8][9])(int*))[5];

实际当中,需要声明一个复杂指针时,如果把整个声明写成上面所示的形式,对程序可读性是一大损害。应该用typedef来对声明逐层分解,增强可读性,例如对于声明:

int (*(*func)(int *p))[5];

可以这样分解:

typedef int (*PARA)[5];
typedef PARA (*func)(int *);

这样就容易看得多了。

Read: 596

关于(*(void(*)())0)()

    前段时间看了这本C Traps and Pitfalls,看到里面有这样的一个语句:
   (*(void(*)())0)();

    初看此语句,让我头皮发麻,不寒而栗呀,我看了好半天书,也只是一知半解,后来在下面两个论坛上分别发一个帖子问了一下:
http://bbs.chinaunix.net/viewthread.php?tid=891271&extra=page%3D2
http://www.vckbase.com/bbs/viewtopic2.asp?rid=2869084&sf=92&forumID=1&pg=4

    首先这是一个函数调用,但是一个特殊的函数调用,在我们普通的C语言程序中是没有任何意义的,甚至不能执行的,我在VC6的环境下写了一个测试例子:
int main()
{
     (*(void(*)())0)();
     return 0;
}

    编译是通过了,但是却在执行的过程中出现了错误。在Linux下也进行了测试,也是编译通过,但运行出现了错误。
    然而,这个并不代表它没有用,它在一些特殊的环境中是有用的,比如在地址0处设置了跳转或是中断处理函数之类的,那么这个函数调用就有用了。
    总结一下我自己的理解和网上网友的理解:
   
    这是一个函数调用,它调用的是地址为0的函数。
如果我们令 f =
*(void(*)())0
那么这个上面的语句可以写成 (f)(),也就是f();这很显然是一个函数调用
而 void(*)()是一个指针类型,它是一个参数为空而返回值为void (实际上也是空)的函数指针类型,(void(*)())0就是把0强制转换成为一个函数指针,
我们可以这样理解
typedef void(*pp)();
   (*(pp)0)();

(void(*)())0这个函数指针指向一个地址为0的函数,如果前面再加一个星号*,那么就是对这个函数的引用,即(*(void(*)())0)就代表了这个函数,后面再加一个()就是对该函数的调用。

Read: 754