• 微软公司软件开发模式简介
    ——摘自北京大学出版社出版的《微软的秘密》一书

      北京大学出版社96年底所出的《微软的秘密》一书是目前我所见到的对微软公司软件产品开发过程介绍的最专业、最深入的一本书。通过本书,我们可以看到微软公司是如何对科学地对软件产品开发进行有效地管理,我想这些经验对于中国的广大软件开发人员,尤其是关心中国软件产业发展的各位朋友是大有益处的。所以特将此书中涉及软件产品开发的部分内容摘录出来(第四章“产品定义与开发过程”),与大家共同分享。本文作为摘录,自然是挂一漏万,所以建议大家若有时间还是找来原书一读。

      在产品定义与开发过程中,微软件遵循着一种可称之为“靠改进特性与固定资源来激发创造力”的战略。该战略可分为五个原则:

      一、将大项目分成若干里程碑式的重要阶段,各阶段之间有缓冲时间,但不进行单独的产品维护。

      二、运用想象描述和对特性的概要说明指导项目。

      三、根据用户行为和有关用户的资料确定产品特性及其优先顺序。

      四、建立模块化的和水平式的设计结构,并使项目结构反蚋产品结构的特点。

      五、靠个人负责和固定项目资源实施控制。

    原则一:将大项目分成若干里程碑式的重要阶段,各阶段之间有缓冲时间,但不进行单独的产品维护。
      项目进度安排与里程碑

      微软通常采用“同步-稳定产品开发法”。典型项目的生命周期包括三个阶段:计划阶段完成功能的说明和进度表的最后制定,开发阶段写出完整的的源代码,稳定化阶段完成产品,使之能够批量生产。这三个大阶段以及阶段间内在的循环方法与传统的“瀑布”式开发方式很不相同,后者是由需求、详尽设计、模块化的代码设计与测试、集成测试以及系统测试组成的。而微软的三个阶段更像是风险驱动的、渐进的“螺旋”式的生命周期模型。

      计划阶段的产品是想象性描述与说明文件,用来解释项目将做什么和息么做。在管理人员拟定进度表、开发员写出代码之前,这些东西都促进了人们对设计问题的思考与。讨论开发阶段围绕三次主要的内部产品发布来进行;称定化阶段集中于广泛的内部与外部测试。在整个产品生产周期中,微软都使用了缓冲时间的概念。缓冲时间使开发组能够对付意外的困难和影响到时间进度的变故,它也提供了一种手段,可以缓和及时发货与试图精确估计发货时间之间的矛盾。

      在开发和稳定化阶段的所有时间中,一个项目通常会将2/3的时间用于开发,1/3的时间用于稳定化。(Office部门副总裁曾这样概述通常的进度:“一般说来,在总的进度表中,用一半的时间写出产品,留下另一半的时间调试或应付意外事故。这样,如果我有一个两年的项目,我会用一年来完成事先想好的东西……如果事情有点麻烦,我便去掉我认为不太重要的特性。”)这种里程碑式的工作过程使微软的经理们可以清楚地了解产品开发过程进行到了哪一步,也使他们在开发阶段的后期有能力灵活地删去一些产品特性以满足发货时期的要求。

      计划阶段

      计划阶段是在一个项目的生命周期中,所有于开发前进行的计划所占用的时间。计划阶段产生出想象性描述、市场营销计划、设计目标、一份最初的产品说明、为集成其他组开发的构件而规定的接口标准、最初的测试计划、一个文档策划(印刷品和联机帮助形式的)以及一份可用性问题清单。计划阶段从想象性描述开始。想象性描述来自产品经理以及各产品单位的程序经理;它是对产品作业的市场营销设想,包括了对况争对手产品的分析以及对示来版本的规划。想象性描述也可能讨论在前一次版本中发现面必须解决的问题以及应添加的生要功能。所有这些都基于对顾客和市场的分析以及从产品支持服务组处得到的资料。

      说明文件从一个大纲开始,然后定义出新的或增加的产品特性,并对其赋以不同的优先级。说明文件只是产品特性的一个预备性概览;从开始开发到项目完成它要增加或变化20% - 30%。虽然在生命周期的后期说明变化一般较小,但越到后期,开发员就越是必须具充分的理由来作改变。

      通常程序经理使用VB创建项目原型。他们也开展设计可行性研究以了解设计中的取舍情况,尽快做出涉及产品说明的决定。

      对于重要产品的说明需由公司高层领导进行复审。对于不太生要的产品,则由部分经理去完成。

      开发阶段

      开发阶段的计划对三四个主要的里程碑版本都个咖分配一组特性,规定出特性的细节和技术上的相关性,记录下单个开发员的任务以及对进度的估计。在开发阶段中,开发员在功能性说明的指导下写源代码,测试员写出测试项目组以栓查产品的特性与工作范围是否正常,用户教育人员则编写出文档草案。

      当测试员发现错误时,开发员并不是留待以后处理,而是马上改正,并在整个开发阶段内使测试不断地、自动地进行。这就改善了产品的稳定性并且使版本发布日期更易估计。当达到项目中的一定阶段点后(40%时),开发员就试图“锁定”产品的主要功能要求或特性,从此只允许小的改动。如果在此点之后开发员想作大的改动,他们必须与程序经理以及开发经理,问题也许还要征求产品部门
  • From:http://www.yangning.com/cgi-bin/topic.cgi?forum=1&topic=77&replynum=last#bottom

    四大要素:
    1.程序的基本工作原理。这些原理性的东西是整个程序的灵魂,学术界搞得所谓的科研,就是这种东西。
    2.基本工作原理的实现方案,即程序的设计方案、核心技术、关键技术等。基本工作原理跟实现方案虽然本质是一致的,但是,在形式上是不同的。因为不同的底层技术供应商把基本原理包装到了不同的产品(函数)中了,所以,程序的架构师需要搞出一套实际的实现方案出来,把工作原理产品化。

    3.项目的整体设计结构。即应该如何将各个模块有效的组织在一起。程序的总体结构设计跟上一条“基本工作原理的实现方案”是不同的,上一条是抓重点,抓关键,而这一条是抓整体,抓大局。因为一个完善的商业化产品仅仅有核心功能是不够的,还必须要提供一系列的辅助功能,这些辅助功能从技术上来讲,是很简单的,但是,内容却很多,很杂,所以,需要好好进行一番规划设计才行。

    4.项目难点。可能存在于第1条中,也可能存在于第2、3条中。难点不一定就是很核心很关键的东西,有时候一个很小的,很不起眼的东西,却很难处理。

    一个原则:层层推进进行分析设计。
    大项目都是由小的模块组成的, 每个模块都包括上述四大要素,所以,整体和局部是一个层层推进,逐级放大的关系。

    分析大型的软件源码,或者是看书,搞研究,其实都是应该按照上述原则进行。

  • 无欲则刚 仁者无敌
    不要想太多 只管做事就好
    无欲则刚 仁者无敌
    不要想太多 只管做事就好
    无欲则刚 仁者无敌
    不要想太多 只管做事就好
    无欲则刚 仁者无敌
    不要想太多 只管做事就好
    无欲则刚 仁者无敌
    不要想太多 只管做事就好
    无欲则刚 仁者无敌
    不要想太多 只管做事就好
    无欲则刚 仁者无敌
    不要想太多 只管做事就好
  • 2004-01-28

    新年目标 - [我的博客]

    1.大方面
    1.考取高程.
    2.考取日语3级.
    3.积极争取职位提升.

    2.小方面
    1.办事要积极主动.
    2.为人要不亢不卑.
    3.不能把事情有留到明天的想法.
    4.不能欠帐.
    5.别人对自己的好处要记得回报.
    6.不要想些没用的东西,做没用的事情.
  • 出处:http://expert.csdn.net/Expert/topic/2528/2528377.xml?temp=.6930353

    我有一个梦,
    在梦里,我拥有一个阿蓝德龙的外号,众mm群星拱月般的围绕着我,我却故装矜持,装作不解风情的不屑一顾,
    梦醒了,却发现别人称我为阿西莫多,镜子中的那个人,依旧一副刚刚交完租的佃户样子;

    我有一个梦
    在梦里,我拥有一个温馨的二人世界,和一个美丽、温柔的女人无比疯狂的彼此相爱
    梦醒了,却发现自己刚刚被一段感情pass掉,心还在隐隐作痛。

    我有一个梦
    在梦里,我拥有一个童话般美丽的家,每天晚上,我穿着睡衣,坐在宽大舒适真皮沙发里,酌着红酒,高级音响中正放着贝多芬,高大的落地窗外可以看到灯火通明的城市全景。
    梦醒了,我发现自己正躺在员工宿舍中双层床的下铺,不得不忍受着上铺那傻b的呼噜。

    我有一个梦
    在梦里,我拥有一个编程大师的称谓,我的著作被众多程序员顶礼膜拜,堪称经典,
    梦醒了,却发现自己依旧是一个三流程序员,刻苦攻读着《xx语言入门篇》;

    我有一个梦,
    在梦里,我拥有一家公司,在我出神入化的经营运作下,逐渐成长壮大,我对我的雇员非常严厉,动不动就被我骂的狗血喷头,但他们都很服我,唯我马首是瞻。
    梦醒了,我发现自己正坐在别人的公司里,在编码第一线充当着廉价劳动力,见了老板,第一个念头就是躲。

    我有一个梦
    在梦里,我是那样的成功,那样的光彩耀人,自我感觉是那样的好,
    梦醒了,我依旧是我,擦一擦嘴角流出的口水,揉一揉脸颊上硌出的键盘印,继续编程.....
  • 出处:http://expert.csdn.net/Expert/topic/2471/2471918.xml?temp=.4795648

    It’s so vivid for us, right?

      我们终于进入了这个社会。从此结束了被学校老师看管的生涯,结束了做父母乖宝贝的日子,也结束从父母兄长那里拿钱的幸福时光。

      我们从家里搬了出来,提着自己半新不旧的行囊找了间不能再廉价的破房子租了下来,开始了闯荡的生活。

    我们的眼光充满了好奇,我们的血液里流淌着激情,我们的钱夹却空前的瘦小。

      在面对第一个老板第一批同事第一份工作的时候,我们是那样的慷慨激昂,我们认为自己无所不能,我们幻想很快就可以打造一片属于自己的天地,我们对未来充满了信心。并且希望从别人艳羡的目光中找到一点点骄傲的资本。

      可是渐渐的我们才知道,其实现实和自己的理想有着天壤之别。我们发现了老板是多么的阴险狠毒同事是多么的势利小气工作是多么的枯燥无趣,我们也发现了房租水电气费把人愁死了。发薪的日子总好像遥不可及,商店里的东西仿佛只是为别人摆设,我们还发现了只有周末跑到母校瞎逛才感觉释然,只有和老同学一起聊天玩耍才真正开心只有在步行街上看美女才不无聊。

      渐渐的我们也学会了泡吧,酒吧迪吧水吧网吧玩具吧都是我们打发无聊时间的场所。可是我们还是泡不到妞,以前自以为是的那些爱情理论泡马子技巧在金钱时代都是狗屁,都出奇的苍白无力。于是我们感叹世界变得太快,快得让我们这些穷小子根本就无所适从。

      渐渐的我们也变得深沉起来,不再为一个很幼稚的笑话就哈哈大笑,不再动不动就乱发牢骚,也不再把内心深处的秘密轻易地跟别人诉说。我们也说不清楚这到底是成熟还是消沉,对着镜子看,却发现里面那张脸陌生得可怕。

      渐渐的我们似乎大彻大悟了,什么都看透了,一切都虚无缥缈了,然后我们什么都很漠然,坐公交车也不让座了,看到小偷偷东西也懒得理了,吃点小亏想想也就算了,但是我们却在每天下班之前发愁晚餐该吃什么了,在大家一起喝茶的时候盘算着自己要不要买单,在临睡之前把这个月的开支算了又算。

      渐渐的我们感觉自己其实什么都不是,没有钱没有名没有地位,身高也太矮了皮肤也太黑了长相也太难看了,什么都要看人家的脸色,走在哪里都似乎低人一等,有时真恨不得割脉上吊服毒跳楼自行了断。

      渐渐的我们也不想看书了,也不想谈理想了,也不想谈前途了,也不想花太多精力胡思乱想。我们也不想听音乐了,也不想看电影了,不过倒时常看些成人的碟子,交流些黄色的笑话。我们开始沉迷于酒液里,沉迷于方城中,沉迷于低级场所内。、
    家的概念越来越模糊了,亲情的感觉越来越遥远了,除了在梦中偶尔回到家乡之外,我们挺多可以借助一条冰冷的电话线和家人说说一些开始偏离生活的话,却看不到老爹老妈又长出了多少根白头发又多了几道皱纹。

      看到有人在球场上酣战,我们似乎也想上去来两脚,其实很久没有运动的身体已经无法支撑我们再跑多远了,而且几乎荒废的球技让我们怀疑自己那些踢球的年岁是不是上辈子的事。

      望着满街穿着前卫的少男少女,我们开始表现出厌恶的表情,却忘了自己前些年其实有过之而无不及。遇到在大庭广众之下举止亲热的学生情侣,我们的目光也变成了不屑,并恶狠狠地骂他们伤风败俗。

      经过彩票销售点的时候,我们忍不住也掏出一点本该买书的钱来买几注,然后天天做梦中了五百万之后多少万买房子多少万买车多少万胡乱挥霍,可是每一次开奖虽然屡屡有人中头奖却始终与自己无缘,于是在短暂的失望之后,我们依然锲而不舍地做着美梦。

      渐渐的我们的人生观、价值观、爱情观也有所改变。我们已经不认为为了往上爬而不择手段有什么不妥,我们对努力就有回报的说法嗤之以鼻,我们嘲笑所谓的贞节观,所谓的责任感,希望甚至去找寻一夜情。

      我们开始关注街上跑的车是宝马还是奥拓,关注哪个酒廊的吧台小姐酒量如何,关注哪款手机用起来更加叉人眼,关注哪个牌子的西服穿起来更有派头。但也就只是关注而已,因为我们清楚无论是宝马还是奥拓,我们都买不起,吧台小姐酒量再不行,我们也不能把人家怎么样,至于手机和西服,还是用自己买了很久的老款式。

      不知从什么时候开始,我们为自己的遭遇感到愤愤不平了,我们越来越看不惯老板狰狞的面目,越来越无法忍受同事的卑鄙龌龊,越来越不堪就这样生活下去。于是我们在感叹运气不好的同时迫切地想改变自己的命运,我们左顾右盼,寻找机会,却始终看不到出路。

      终于有一天,我们像火山爆发一样,一冲动之下把老板炒了。收拾东西昂然地走出办公室的那一刻我们有英雄离去那种豪迈与无悔,只从同事愕然与嘲讽夹杂的眼神中隐隐看到一丝无奈,却不知道等待自己的,将是无尽的痛苦与折磨。

      我们很快发现了虽然自己拥有并不低的学历和一定的工作经验,并像跑场子一样从这家公司跑到那家公司,一次接一次地应聘,可是根本就无法找到适合的工作。

      时间一天一天过去,工作依然遥远得不知子丑寅卯,钱包越来越瘪了,交房租的日子也越来越近了,我们心如火焚,有
  • corporate lesson1
    当老婆刚刚冲完澡出来,老公正要开始淋浴时,门铃响了。
    在几秒争吵谁该去应门之後,老婆放弃了,裹了条毛巾急忙下去开门。
    她打开门看见bob,他的邻居。
    在她还没开口之前,bob就说:「如果你把那条毛巾拿下,我就给你$800!」
    老婆想了想,就脱下毛巾处裸站在bob面前,过了几秒bob给了钱就走了。
    老婆困惑又兴奋她的好运的裹上毛巾上楼。
    当她回到浴室老公问她:「刚刚是谁ㄚ?」
    「隔壁的bob啦!」她回答。
    「很好,」老公说「那他有没有拿他欠我的$800还我吗?」

    opportunity.故事的寓意
    在未了解事情的漏洞之前,永远不要轻易自行判断而造成错误,而且还不知道自己有多难堪。

    corporate lesson2
    有个牧师开车在路上,见到路旁有个修女,便停车主动载她一程。
    她进车後便翘起脚来,让她可爱的美腿从长袍中露了出来。
    牧师看了一眼高兴的差点让车子出了意外。
    在控制车子後,他偷偷摸摸的将她的手往美腿上移动。
    修女看了看他便说:「神父,记得圣诗129吗?」
    神父脸红连忙道歉,他被迫移开他的手。
    但是他的视线却离不开他的美腿。
    在几次换档之後,他的手又再次滑向美腿。
    修女又说:「神父,记得圣诗129吗?」
    神父又在一次道歉:「对不起,姊妹,肉体是虚弱的。」
    到达修道院後,修女下车给了他一个寓意深长一眼就走了。
    当神父回到教堂,他急忙拿出圣经想找出圣诗129是什么。
    圣诗129节:「走向前并寻求,再更深入一点,你会找到荣耀的。」

    opportunity.故事的寓意
    永远对你的工作保持熟悉,不然你会错过很多机会的。

    corporate lesson 3
    业务代表,行政职员,经理一起走在路上去吃午餐,意外发现一个古董油灯。
    他们摩擦油灯,一个精灵从一团烟雾中碰了出来。
    精灵说:「我通常都给每个人3个愿望,所以给你们每个人一人一个。」
    我先!我先!」职员抢著说:「我要到巴哈马,开著游艇,自在逍遥。」
    噗!她消失了。
    惊吓之後,
    「换我!换我!」业务代表说:「我要在夏威夷,和女按摩师躺在沙滩上,还有喝不完的pina coladas(凤椰汁),和生命之爱。」
    噗!他消失了。
    「好了!现在该你了!」精灵对经理说。
    经理说:「我只希望他们两个吃完午餐後回到办公室。」

    moral of the story:
    always let your boss have the first say.

    From:http://expert.csdn.net/Expert/topic/2636/2636409.xml?temp=.3995172

    故事的寓意:永远让你老板先说
  • 在Qt中进行绘图操作的时候我们常常需要对位图进行缩放,利用QWMatrix类 就可以很轻松的完成此功能,示例代码如下:
    QPixmap pm ;

    // do something to pm

    if ( !pm.isNull() )
    {
    QWMatrix m;//创建一个QWMatrix类的对象
    m.scale(0.5f, 0.5f);//设立一个进行缩小到1/2的变换矩阵
    pm = pm.xForm(m);//进行变换操作
    }

    大家有兴趣可以自己尝试一下.

    junglesong 编辑
    2004-1-26
  • 这几天在上古历史,程序开发几个栏目都增添了一些新的日志,大部分是转载的,少部分是自己写的.

    vb专辑中的新文章不错的,对网页采集器,灌水机制作有兴趣的人可以看看.

    我是打算把Qt专辑弄好的,这方面国内弄的人比较少,有时候找个小问题都要满世界的跑,我有幸做过两个QT相关的项目,尽量把自己知道的写出来,希望对别人有些用处.


    junglesong

    2004-1-26

  • 以太阳的名义

    黑暗公开地掠夺

    沉默依然是东方的故事

    人民在古老的壁画上

    默默地永生

    默默地死去
  • From:http://www.blogchina.com/new/display/2529.html

    在喧闹、混杂的生活中

      你应该与你的心灵和平相处

      尽管这世上有很多假冒和欺骗

      有很多单调乏味的工作

      和众多破灭的梦幻

      它仍然是一个美好的世界

      记住:你应该努力去追求幸福。

      是的,记住:你应该努力去追求幸福。

  • From:http://www.microsoft.com/china/msdn/workshop/scrape.asp

    利用 Microsoft 的 HTML 分析器来获得 Web 站点的数据
    Jeremy Rule
    Microsoft Corporation
    2000年5月
    摘要: 本文讨论如何收集来自 Web 的信息,并借助 Internet Explorer 的可重用分析器组件,将它分布到其他 Web 页或数据库。(打印共 7 页)

    程序员面临的一个共同任务就是收集 Web 站点的数据,并将它分布到数据库或其他 Web 页。例如,程序员可能需要从气象站点获得天气预报图,从在线股票经纪人那里获得股票报价,以及从新闻站点获得行业新闻。然后,这些信息被放在一个 Web 页上,供 CIO、商人或销售经理使用。或者,也许程序员需要跟踪历来的气象资料,并需要每天将来自气象站的天气预报信息存入数据库。其应用不胜枚举。

    过去,这些选择相当受限制。现在,通过使用象 WinInet.dll 这样的 HTTP 组件或许多其他第三方组件,您就可以获取 Web 页,并利用几百种字符串处理功能来获得网页中您所感兴趣的部分。这一技术已在应用,但很不理想。如果您致力于计算机科学(或者有足够的时间),就会为 HTML 创建一个分析器,以标记 Web 页,然后分析您需要的网页部分。不过,由于 Internet Explorer 的体系结构中已包含了可重复使用的用分析器,这些都不需要了。

    Internet Explorer 不只是一个程序,更是许多可重复使用组件的集合与容器。在拆取 Web 页时,最有意思的两个组件是 shdocvw.dll 和 mshtml.dll。第一个组件 shdocvw.dll,包含称为 WebBrowser 的 Microsoft(R) ActiveX(R) 控件,它真实地显示 Web 页。在运行 Internet Explorer 时,显示 Web 页的主窗口就是这样的控件。第二个组件 mshtml.dll,含有能分析 WebBrowser 控件中所包含文档的 HTML 分析器。

    可能有这种情况,在您的应用程序内部,已经用 WebBrowser 控件来驻留 Web 页,但仍需要重新创建一个小浏览器来启动 Web 页的拆取。

    在文件菜单上,请单击新建工程,以创建“标准 EXE”,然后在工程菜单上单击部件,以添加 Microsoft HTML Object Library 和 Microsoft Internet Controls。(见图 1。)


    图 1.

    在工具箱中,可看见 WebBrowser 组件。拖动其中之一,文本框和主窗体上的命令按钮。将此文本框的 Text 属性设置为 “http://moneycentral.msn.com/”,将此命令按钮的 Caption 属性设置为“浏览(&B)”。(见图 2。)


    图 2.

    双击该命令按钮,然后在事件处理器中放入下列代码,导航至文本框中命名的 Web 站点:
    Private Sub Command1_Click()
    WebBrowser1.Navigate Text1.Text
    End Sub

    保存并运行该程序。试着按浏览按钮,导航到文本框中指定的站点。您已经创建了一个基本的 Web 浏览器 — 就其本身而言没什么用,甚至没什么意义,但它却是迈向 Web 拆取技术的第一步。


    回到工程中,在代码窗口中选择 WebBrowser1 对象,然后选择 DocumentComplete 的事件处理器。一旦整个 Web 页下载到此浏览器中,即触发该事件:
    Private Sub WebBrowser1_DocumentComplete_
    (ByVal pDisp As Object, URL As Variant)

    End Sub

    传递到该事件中的 URL 就是我们导航所至的位置,它在日后确定浏览器所在的页面时将更为有用。WebBrowser 控件有一个属性称为 Document(文档),可将其视为 IHTMLDocument 来处理:

    Private Sub WebBrowser1_DocumentComplete(_ ByVal pDisp As Object, URL As Variant)
    Dim Doc As IHTMLDocument2
    Set Doc = WebBrowser1.Document
    //下一步:分析该文档
    End Sub

    较新的 IHTMLDocument2 具有 IHTMLDocument 中无法使用的特性。可对系统使用 IHTMLDocument 替代老版本的 Internet Explorer,如果您有勇气的话,甚至可以使用 IHTMLDocument3。补充说明一下,我们假设您已经导航到 Word 文档或 XML 文档,而非 HTML 文档。不要将变量 doc 声明为 IHTMLDocument2,可将其声明为 Word 的文档或 XML 的 DOMDocument。

    在进行下一步之前,理解 HTML 文档的结构是非常重要的。和 XML 不一样,HTML 文档的组合有一定的自由度。例如,您会遇到未关闭标记的 HTML 文档。HTML 文档确实有某种结构。结构好的 HTML 文档通常具有下列元素:

    <HTML>
    <HEAD>
    header information like the <TITLE>
    </HEAD>
    <BODY>
    elements like <TABLE> and <A> and <IMG>
    </BODY>
    </HTML>

    请注意 HTML 的树状结构。标记包含标记又包含标记,如此等等。特别是,每一个标记元素都包含一个 0 到 n 个标记元素的集合。<TABLE> 标记可以包含 <TR> 标记。每个 <TR> 标记可以包含 <TD> 标记,后者又可以包含其他标记如锚或图像等。

    现在,分析整个 http://moneycentral.msn.com/,并在带 MSFT 符号的页填上第二个 <INPUT> 标记。然后,调用此窗体上的提交:
    Private Sub WebBrowser1_DocumentComplete(ByVal pDisp As Object, URL As Variant)
    Dim doc As IHTMLDocument2
    Set doc = WebBrowser1.Document

    If URL = _
    "http:/
  • 实现和IE浏览器交互的几种方法的介绍
    浙江大学计算机系
    胡朝晖 陈奇 俞瑞钊
    ---- 1.引言

    ---- 如何实现对IE浏览器中对象的操作是一个很有实际意义问题,通过和IE绑定的DLL我们可以记录IE浏览过的网页的顺序,分析用户的使用行为和模式。我们可以对网页的内容进行过滤和翻译,可以自动填写网页中经常需要用户填写的Form内容等等,我们所有的例子代码都是通过VC来表示的,采用的原理是通过和IE对象的接口的交互来实现对IE的访问。实际上是采用COM的技术,我们知道COM是和语言无关的一种二进制对象交互的模式,所以实际上我们下面所描述的内容都可以用其他的语言来实现,比如VB,DELPHI,C++ Builder等等。

    ---- 2.IE实例遍历实现

    ---- 首先我们来看系统是如何知道当前有多少个IE的实例在运行。

    ---- 我们知道在Windows体系结构下,一个应用程序可以通过操作系统的运行对象表来和这些应用的实例进行交互。但是IE当前的实现机制是不在运行对象表中进行注册,所以需要采用其他的方法。我们知道可以通过ShellWindows集合来代表属于shell的当前打开的窗口的集合,而IE就是属于shell的一个应用程序。

    ---- 下面我们描述一下用VC实现对当前 IE实例的进行遍历的方法。IShellWindows是关于系统shell的一个接口,我们可以定义一个如下的接口变量:

    SHDocVw::IShellWindowsPtr m_spSHWinds;
    然后创建变量的实例:
    m_spSHWinds.CreateInstance
    (__uuidof(SHDocVw::ShellWindows));
    通过IShellWindows接口的方法GetCount
    可以得到当前实例的数目:
    long nCount = m_spSHWinds- >GetCount();
    通过IShellWindows接口的方法Item
    可以得到每一个实例对象
    IDispatchPtr spDisp;
    _variant_t va(i, VT_I4);
    spDisp = m_spSHWinds->Item(va);
    然后我们可以判断实例对象是不是
    属于IE浏览器对象,通过下面的语句实现:
    SHDocVw::IWebBrowser2Ptr spBrowser(spDisp);
    assert(spBrowser != NULL)
    ----在得到了IE浏览器对象以后,我们可以调用IWebBrowser2Ptr接口的方法来得到当前的文档对象的指针: MSHTML::IHTMLDocument2Ptr spDoc(spBrowser->GetDocument());

    ---- 然后我们就可以通过这个接口对这个文档对象进行操作,比如通过Gettitle得到文档的标题。

    ---- 我们在浏览网络的时候,一般总会同时开很多IE的实例,如果这些页面都是很好的话,我们可能想保存在硬盘上,这样,我们需要对每一个实例进行保存,而如果我们采用上面的原理,我们可以得到每一个IE的实例及其网页对象的接口,这样就可以通过一个简单的程序来批量的保存当前的所有打开的网页。采用上面介绍的方法实现了对当前IE实例的遍历,但是我们希望得到每一个IE实例所产生的事件,这就需要通过DLL的机制来实现。

    ---- 3.和IE相绑定的DLL的实现

    ---- 我们介绍一下如何建立和IE进行绑定的DLL的实现的过程。为了和IE的运行实例进行绑定,我们需要建立一个能够和每一个IE实例进行绑定的DLL。IE的启动过程是这样的,当每一个IE的实例启动的时候,它都会在注册表中去寻找这个的一个CLSID,具体的注册表的键位置为:

    HKEY_LOCALL_MACHINE\SOFTWARE\Microsoft\Windows
    \CurrentVersion\Explorer\Browser Helper Objects
    ---- 当在这个键位置下存在CLSIDs的时候,IE会通过使用CoCreateInstance()方法来创建列在该键位置下的每一个对象的实例。注意对象的CLSIDs必须用子键而非名字值的形式表现,比如{DD41D66E-CE4F-11D2-8DA9-00A0249EABF4} 就是一个有效的子键。我们使用DLL的形式而非EXE的形式的原因是因为DLL和IE实例运行在同一个进程空间里面。每一个这种形式的DLL必须实现接口IObjectWithSite,其中方法SetSite必须被实现。通过这个方法,我们自己的DLL就可以得到一个指向IE COM对象的IUnknown的指针,实际上通过这个指针我们就可以通过COM对象中的方法QueryInterface来遍历所有可以得到的接口,这是COM的基本的机制。当然我们需要的只是IWebBrowser2这个接口。

    ---- 实际上我们建立的是一个COM对象,DLL只不过是COM对象的一种表现形式。我们建立的COM对象需要建立和实现的方法有:

    ----1. IOleObjectWithSite接口的方法SetSite必须实现。实际上IE实例通过这个方法向我们的COM对象传递一个接口的指针。假设我们有一个接口指针的变量,不妨设为:

    ----CComQIPtr< IWebBrowser2, &IID_IWebBrowser2 > m_myWebBrowser2;

    ---- 我们就可以在方法SetSite中把这个传进来的接口指针赋给m_myWebBrowser2。 2. 在我们得到了指向IE COM对象的接口后,我们需要把自己的DLL和IE实例所发生的事件相关连,为了实现这个目的,需要介绍两个接口:

    ----(1) IConnectionPointContainer。这里使用这个接口的目的是用来根据它得到的IID来建立和DLL的一个特定的连接。比如我们可以进行如下的定义:

    CComQIPtr< IConnectionPointContainer,
    &IID_IConnectionPointContainer >
    spCPContainer(m_myWebBrowser2);
    ----然后,我们需要把所有IE中发生的
  • 一、调试版本与发布版本

      有时程序能在调试版本运行但不能运行于发布版本,反之也有可能。一般说来,一个发布版本意味着某些类型的优化,而一个调试版本则没有优化。下面我们来看看它们的区别:

    1、特别针对调试版本的编译选项

    (1)/MDd,/MLd或者/MTd

      调试版本的运行时刻库有调试符号,使用了调试堆,调试堆的目的是发现内存破坏和内存泄漏,并且向用户报告源代码的哪个地方出了问题。特性:

    .调试版本的运行时刻库对内存的分配作了跟踪,允许用户检查内存泄漏。

    .在刚分配的内存里写上0xCD的字节模式,用0xCD来填充刚分配的内存,有助于发现数据未被初始化的错误。

    .在被释放的内存写上0xDD的字节模式,有助于发现已被释放的内存。

    .在缓冲区的两边分配了四字节的保护数据,并用0xFD的字节模式作初始化,来检查写内存的上溢出和下溢出。

    .在每个内存分配的地方对源代码文件名和行号作了记录,有助于用户在源代码中对内存分配进行定位。

    (2)/Od

      这个选项用来关闭优化开关。因为未被优化的代码直接对应于源代码,所以比优化后的代码更容易读懂。未被优化的代码编译和链接会更快,会有更短的调试周期。而由于优化,发布版本不见得会比调试版本运行得好,优化代码要求编译器做一些假设,去除冗余,但有时这个假设是错误的,并且去掉的冗余也有可能隐藏错误。如发布版本的帧指针(EBP寄存器)省略(FPO)隐藏了函数原型不匹配的错误;在同步异常模式(只能由throw语句抛出,编译器默认,由/GX编译选项设置)下,异常处理程序可能被优化掉,会阻止程序中的C++异常处理代码安全地捕获结构异常,在这种情况下,你必须使用异步异常模式(采取任何指令都会产生异常的机制,由/Eha编译选项设置)。

    (3)/D “_DEBUG”

      打开条件编译调试代码开关。只有这个符号被定义,调试代码才会被编译,MFC使用_DEBUG符号来确定到底链接的是哪个版本的MFC类库。在调试版本中,内联默认情况下是被关闭的。

    (4)/ZI

      创建编辑继续(Edit and Continue)的程序数据库。这个选项会打开/GF编译选项,/GF编译选项会消除重复字符串,并将字符串放到只读内存。编辑继续功能需要获取存储在PDB文件里的特殊信息来使得代码的修改对调试器有效。如果被修改文件对应的信息不在PDB文件里,编辑继续功能就不能进行,而且在调试过程中对代码的任何修改都会出现下面的提示信息“One or more files are out of date or do not exist.”。

    (5)/GZ

    在调试版本中用来发现那些在发布版本里才发现的错误。其作用如下:

    .用0xCC模式初始化自动(本地)变量。

    .在通过函数指针调用函数时,检查栈指针,确认是否有调用规则不匹配。

    .在函数最后检查栈指针是否被改变。

    (6)/Gm

      打开最小化重新链接开关,减少链接时间。

    2、特别针对发布版本的编译选项

    (1)/MD,/ML或者/MT

      使用发布版本的运行时刻库。

    (2)/O1或者/O2

      打开优化开关,使得程序会最小或说速度会最快,优化器还可能发现代码中潜在的错误,而这些错误可能会被调试版本掩盖。

    (3)/D “NDEBUG”

      关闭条件编译调试代码开关。

    (4)/GF

      消除重复字符串并将它们放到只读内存中以避免被错误地修改。

    (5)/Zi

    创建包含调试符号的程序数据库。

      如果一个错误只发生在发布版本里,除非你是个汇编高手,否则你需要调试符号来提示你到底程序出现了什么问题,调试符号保存在程序的数据库文件(PDB)中。Visual C++的AppWizard默认情况下没有为发布版本创建调试符号。为创建调试符号,打开工程设置对话框,选择Win32 Release,在C/C++标签里选择Common类,在调试信息里,如果是发布版本选择Program Database,如果是调试版本选择Program Database for Edit and Continue(编辑继续选项与优化链接不相容,不适于发布版本)。在Link标签里选择Debug类,然后选择Debug Info和Microsoft format选项,最好不要选择Separate types选项,这样所有的调试信息才会被合并到单独的一个PDB文件中。对于发布版本,选择Link标签,在Project options对话框的最后加上“/OPT:REF”,这个选项使得不被引用的函数和数据不会出现在可执行文件中,避免了文件的无谓增大。对于调试版本不要使用这个选项,它会关闭增量链接(incremental linking)。

    二、Visual C++编辑器的“设置”菜单

      当你打开或新建一个包含至少一个工程的Workspace后,Visual C++的Project菜单中的“Settings…”命令就变为有效,选择它或者按下热键Alt+F7后,便可调出工程设置对话框,这里面的选项将影响整个工程的建立和调试过程,因此很重要。

      在这个对话框中,左上方的下拉列表框用于选择一种工程配置,包括有Win32 Debug、Win32 Release和All Configurations(指前两种配置一起),某些选项在不同的工程配置中有不同的缺省值。左边的树形视图给出了当前工程所有的文件及分类情况。下面我们就以Win32 Debug为例来看看与工程有关的的四个主要选项卡的各自功能与含义(一共有
  • 为了更好地对程序调试,可以使用如下方法:使用断言、使用跟踪语句、使用异常和返回值。

    一、断言

    1、基本概念

      断言是一种让错误在运行时候自我暴露的简单有效实用的技术。它们帮助你较早较轻易地发现错误,使得整个调试过程效率更高。

      断言是布尔调试语句,用来检测在程序正常运行的时候某一个条件的值是否总为真,它能让错误在运行时刻暴露在程序员面前。使用断言的最大好处在于,能在更解决错误的发源地的地方发现错误。断言具有以下特征:

    .断言是用来发现运行时刻错误的,发现的错误是关于程序实现方面的。

    .断言中的布尔表达式显示的是某个对象或者状态的有效性而不是正确性。

    .断言在条件编译后只存在于调试版本中,而不是发布版本里。

    .断言不能包含程序代码。

    .断言是为了给程序员而不是用户提供信息。

      使用断言最根本的好处是自动发现许多运行时产生的错误,但断言不能发现所有错误。断言检查的是程序的有效性而不是正确性,可通过断言把错误限制在一个有限的范围内。当断言为假,激活调试器显示出错代码时,可用Call Stack命令,通过检查栈里的调用上下文、少量相关参数的值以及输出窗口中Debug表的内容,通常能检查出导致断言失败的原因。_ASSERTE宏(属于C运行时间库)还能在断言失败时显示出失效断言。下面我们讨论一下MFC库中的断言。

    2、MFC库中的断言

    (1) ASSERT(布尔表达式)

    用MFC时最好选择ASSERT宏,它的优点是即使出现了WM_QUIT消息也能显示断言失效消息框。

    (2) VERIFY(布尔表达式)

    VERIFY宏中的布尔表达式在发布版本中被保留下来。VERIFY宏简化了对函数返回值的检查,一般用来检查Windows API的返回值。由于VERIFY宏里的布尔表达式在发布版本里保留了下来,因此最好尽量不要使用这个宏以实现程序代码和调试代码的完全分离。

    (3 )ASSERT_VALID(指向CObject派生类对象的指针)

    ASSERT_VALID宏通过调用重载的AssertValid函数来确定指向CObject派生类对象的指针是否有效。无论你什么时候从CObject派生类中得到一个对象,在对这个对象做任何操作之前都应该调用ASSERT_VALID宏。

    (4) ASSERT_KINDOF(类名, 指向CObject派生类对象的指针)

    这个宏用来验证指向CObject派生类对象的指针是否从某个特殊类中派生,在调用它之前先调用ASSERT_VALID宏。只有在很特殊的场合下才用得到,如检测编译器可能错过的对象类型问题。

    此外,还有两个没有正式文件的ASSERT宏的变种:ASSERT_POINTER(指针,指针类型),ASSERT_NULL_OR_POINTER(指针,指针类型)。

    3、什么时候使用断言

      把断言看作一种简单的制造栅栏的方法,这种栅栏能使错误在穿过自己时暴露。

    .检查函数的输入

    .检查函数的输出

    .检查对象的当前状态

    .坚持逻辑变量的合理性和一致性

    .检查类中的不变量

    公有成员函数比私有和保护的成员函数需要更全面的断言。

      不正确地使用断言会导致错误。断言应该检测那些在程序正常运行的时候永远都不可能出现的状态。断言是用来揭示错误的,而不是用来纠正运行时刻错误的。

    4、断言与防御性编程(Defensive Programming)

      断言在调试的时候向程序员揭示运行时刻错误(调试版本里),而防御性编程使用户在运行程序(发布版本里)时,当出现意外情况时程序仍能继续工作。实际上,防御性的编程要求程序在检测到意外时返回一个“安全”的值(比如布尔函数返回false,指针和句柄返回空值),一个错误代码或者抛出一个异常来解决问题。特定的防御性编程技术包括:处理无效函数参数和数据、出现问题的时候程序失败、检查临界函数返回的错误代码以及处理异常。需要防御性编程的标准问题包括:错误的输入数据、内存或者硬盘空间不够、不能打开一个文件、外部设备不能访问、网络连接不上或者甚至在程序中还有错误,目的是保持程序的运行状态。如果你的程序是防御性的,别忘了使用断言。如果你使用断言,也别忘了防御性编程。这两种技术最好结合在一起使用。

    二、跟踪语句

    1、基本概念

      跟踪语句(trace statements)可使程序执行,并使程序员可对可变值进行查看。它们提供了一个用于观察的程序,并且独立于一个交互式的调试器,但是最具有特色的是它们常用于对调试器提供的信息进行补充。在VC中,跟踪消息通常输出到输出窗口中的Debug标签,也可以重新输出到一个文件中。跟踪语句的特性如下:

    .跟踪语句用于报告代码中重要的运行事件。

    .跟踪语句的编译通常是有条件的,并只存在于调试版本中,而在发布版本中不被编译。

    .跟踪语句不能包含程序代码或对程序代码有间接的影响作用。

    .跟踪语句的目的是向程序员提供信息,而不是向用户。

    跟踪语句也是调试语句,它可以执行程序,并且在运行中程序员可以查看变量。跟踪语句对于那些使用交互式调试器很难调试的程序是很有效的。

    跟踪语句和断言的区别如下:

    .跟踪语句是无条件的,断言是有条件的布尔语句。

    .跟踪语句用于显示程序执行和变量值,不直接显示bug,断言用于显示出bug。

    .跟踪语句将信息输出到调试窗口
  • 编写易于调试的VC代码


    一 程序的设计

      要避免错误,首先要从好的设计开始。对于程序的设计,需考虑到程序的两个特性:

      1简单性

      大多数常见的错误来源于程序设计中不必要的复杂成分。一个好的设计应该反映问题本身的要求,而不必为了刻意追求“满足将来的需要”而添加不必要的特性。实际上,简单优雅的设计比那些复杂的设计更能迎合未来的需求。

      2 耦合性

      耦合(decoupling)性用来衡量不同对象之间的依赖程度。松耦合的程序易于理解和实现,易于测试和维护,且这种程序包含错误的可能性小,错误也较容易发现和清除。

    二 编程风格

      编程风格是个人问题,有很大的随意性。一个好的编程风格不仅让代码易理解,也易于调试。好的编程风格包括:

      1 清晰地书写代码

      如果没有必要,尽量不要使用语言中的高级特性,因为这些特性不易于理解和调试。使用大多数程序员都能理解的语言成分来书写代码不易犯错且易于理解和维护。

      2 编写结构良好的代码

      当程序崩溃时所能得到的最基本的调试信息是源代码文件、问题所在行的行号和一个调用栈(call stack)。调用栈是调试程序时最有帮助的部分,它提供错误出现的上下文,也就是带参数的函数调用序列。你书写的代码结构越好,调用栈就能给你越多信息。

      3 使用良好的标识符

      一个好名字能使你的代码更容易被理解和维护。流行的匈牙利命名法(Hungarian Notation)实际上是把标识符的意义和表示方法结合起来。现在,匈牙利命名法表现出不少的局限性,匈牙利命名法过于看重前缀的作用,对一个变量的表达信息不完整,实际上并没有传递多少有用信息,它使代码难于阅读,难以维护。一个好的命名传统是指示出变量的作用域以便在需要的时候检查它的定义,并明确地指出一个变量是全局的、局部的还是成员数据。依赖变量的定义比依赖匈牙利前缀更加有用和可靠。

      好的名字能够用平常的语言概括出该标识符所代表的实体的含义。在选择类、函数、变量的名字时可以考虑以下几个原则:

        取简单的描述性名字,好的名字能简要地概括出这个标识符代表的含义。

        避免简写,简写使标识符难于阅读和记忆,尽量使用混合大小写的完整的单词。

        避免相似性的文字,避免混淆。

        避免采用一般的或随机产生的名字,而应采用有实际意义的名字。如欲从按钮类派生位图按钮,取一个CBitmapButton,而不是CMyButton。

      4 用简单的语句行

      在VC中,一行可写多个语句。但调试是面向行的,过于复杂的行难于调试。因此,从调试的角度出发,每一个语句都应独自成行。

      5 使用统一的排列

      统一的排列方式使类、变量的定义和语句更加明显。

      6 用括号使书写清晰

      你不一定能都记住各种运算符的优先级和结合律,而使用多余的括号并不影响编译后的代码。因此,如果你不能确定是否需要括号时,请加上它。

      7 使用好的注释

      用好的注释能使你的代码不易出错,而且便于其他程序员阅读,便于理解和维护。

    三 编写程序时应注意的问题

      1 充分利用VC++的特性

      可用下列技术来充分利用VC++的编译器的特性:

      (1)用const代替#define来创建常量;

      (2)用enum代替#define来创建常量集合;

      (3)用内联(inline)函数代替#define;

      这三种技术用C++而不是C预处理。使用预处理的问题在于编译器对于预处理器所作的事情一无所知,因此无法用数据类型检查错误和不一致的地方。预处理的名字不在符号表里,因此也不能用调试工具来检查预处理常量。相似地,预处理宏被编译进去,不能用调试工具跟踪。编译器能充分了解const、enum和inline语句,从而能在编译的时候对出现的问题发出警告。

      但预处理在很多调试代码中起重要作用。调试代码经常需要从非调试代码里面得到不同的行为,而最有效的办法就是让预处理为调试创建不同的代码。

      (4)用new和delete代替malloc和free;

      在创建对象、类型的安全性和灵活性方面。使用new/delete比malloc/free要好。另外,new可被重载,提供了更大的灵活性。

      (5)用输入输出流(iostreams)代替stdio。

      使用C++输入输出流(<<和>>)而不使用C标准输入输出库(printf/sprintf和scanf/sscanf),有利于安全性和扩展性。从调试的角度来看,标准输入输出函数的最大问题在于编译器不能对控制流参数进行任何类型检测,而输入输出流的任何问题都能在编译时检测出来。

      2 使用头文件

      要在头文件中声明所有共享的外部符号,而且保留函数原型中的参数名。把所有的共享定义放在头文件中,不要在.cpp文件里面看到extern关键字。

      3 初始化变量

      在使用变量之前一定要把它们初始化。在初始化之前就使用变量肯定会产生错误。通常不需对对象进行初始化,对对数据成员应在构造函数中初始化。必须明确地为在栈中和堆中分配的数组和数据结构进行初始化。对于对象,应该初始化每个需要初始化的数据成员。因为变量的使用是由优
  • 从《史记·鲁世家》看西周积年与武王克商年代
    曹定云 中国社科院 考古研究所


    从《史记·鲁世家》看西周积年与武王克商年代

     

    [摘要] 武王克商年代,是中国古史研究中的难点,也是这次“夏商周断代工程”中需要解决的 重点课题之一。本文对《史记·鲁世家》所载各位鲁公在位年数的研究,证实从鲁伯禽即位至真 公十四年乃西周共和元年,亦即公元前841年,故伯禽即位当在公元前1043年。根据《召诰》、 《洛诰》所载历日的考证,成王元年当在公元前1042年,而武王克商后只在位二年,故武王克商 当在公元前1044年。
    [关键词]  史记;西周积年;鲁世家;武王克商年代;伯禽
    [中图分类号]K244   文献标示码]A [文章编号]1001-0238(2000)04-0017-07

    一、武王克商之年的探讨途径


      西周积年与武王克商年代是古史研究中的难点,也是这次“夏商周断代工程”需要解决的重点课题之一。尤其是武王克商年代,是殷周历史的分界线。它的确立,不仅关系到周史, 而且也关系到殷史。正因为如此,武王克商年代,一直为史学家们所关注。
    我国自汉代刘歆以后,就不断有学者对武王克商年代进行推算。学者们采用的,大多是历史学方法,先推算西周积年,然后再得出武王克商年代。从理论上讲,这种方法是最直接、最可靠的方法。但实际情况并非如此。由于史载不详,各家对西周积年的推算互不相同,因而对武王克商年代的推断就相距甚远,其中最早者与最晚者,相差竟达百余年。此中存在的问题就可想而知了。
      近代以来,学者们对武王克商之年的研究,除继续历史学的方法外,开始另辟溪径。其一,是从金文历谱角度研究西周各王在位年数与西周积年,最后推断武王克商年代。这种方法实际是历史学方法的扩展。其二,是用天文学方法,即根据武王伐纣时的天象和历日记载,推断武王克商年代。从理论上讲,这两种方法也都是可行的,但实际上仍存在诸多问题。从金文历谱角度进行研究,主要是利用西周金文中的纪年铜器铭义。然而,目前学术界对西周金文中的月相辞语解释各不相同,有的甚至互相对立,至今难以达到共识,这严重影响了对西周金文历谱的研究;况目,金文历谱资料也很难齐全,以达满意之结果。因此,真正完整的西周金文历谱的建立,可能还有较长的路要走,还需要不断地探索。从天文角度进行研究,不失为一种有效途径。但它的前提条件是:①武王伐纣时的天象和历日记载必须准确可靠;②研究方法必须科学。而实际情况是,史籍中有关武王伐纣时的天象记载并非都是当时的真实记载,其中有些是后人掺加的。这里就存在对史籍中天象材料进行筛选和鉴别,要去粗取精、去伪存真。目前中外学者对武王伐纣时的天象看法不尽相同,推算的武王克商年代也互有歧异(班大为推断为公元前1046午,见《天命的宇宙-一政治背景》 Early China ,20期,1995年;江晓原等推断为公元前1044年,见《武王代纣时之天象研究》,《自然科学史研究》1999年4期)他们的结论正确与否,也须要用历史学方法进行检验。
      目前“夏商周断代工程’已进入最后阶殷,解决这一问题的时机已经成熟。基于这一考虑,笔者打算采用历史学方法,从研究西周积年入手,对武士克商之年再行探讨,并请专家指正。

    二、西周积年与鲁公在位年数


      古本《竹节纪年》云:“自武王灭殷,以至幽王,凡二百五十七年。”竹书成于魏襄王时,有信史之誉。但该书对西周积年之记述,迄今未得学界认可,记载之误,已是学界公认的了。
    《史记》关于西周历史年代的记述可以分为两大殷:武王克商至厉王奔彘为第一殷;共和元年至幽王十一年为第二殷。第二殷各王年数是清楚的:共和14年,宣王 46年,幽王 11年,合共对71年。第一殷各王年数记录甚少,只记武王2年,周公行政7年,穆王55年,厉王37年,其余各王均无记载。因此,我们无法根据(史记》得出西周积年之总数。后来的一些著述,例如《今本竹书纪年》、《三统历》、《皇极经世》、《帝王世纪》等,分别给出了西周各王的在位年数,推算出西周积年分别为280年、352年、346年。上述之推算均无可靠材料为依据,因而不可置信。
      司马迁在《史记》中,对共和以前的西周各王年数虽缺载,但他在《史记·鲁世家》中,对除伯禽以外的各位鲁公在位年数均有详细记录。他们是:考公4年,炀公6年,幽公14年,魏公50年,厉公37年,献公32年,真公30年……。这些年数为共和以前的西周积年奠定了坚实
    的某础。
      共和元年是鲁公何年,是问题讨论的关键。《鲁世家》载:“真公14年,周厉王无道,出奔彘,共和行政。”这一记载极为重要:它指明共和元年乃真公十四年、《史已》卷14《十二诸侯年表》于共和元年内记:“真公15年,一日十四年。”此中前一句是错的,后一句是对的。对此,张汝舟曾作过精辟分析,指出《年表》此处之先(张汝舟《西周考年》,〈〈二毋室古代天文历法论丛》),又见《武王克商之年研究》第161页,北京师范大学出版社,1997年)。共和元年乃公元前841年,这就在西周年代与鲁国年代的关系中建立了一个等位的标尺。
      鲁国是用公封地,伯禽乃周公长子。伯禽何时即位,《史记
  • 自跋二

    昆仑四水问题,以《旧约·创世纪》伊甸四河,最难解决。学者虽知有二河,一曰替格
    里斯,一曰幼发拉底斯,其他二河,则聚讼纷纷,迄无定论。以替幼两河为据,古人已代我
    等觅出,其他二水果何在乎?余初以河水为替格里斯,弱水即青水,为幼发拉底斯,黑水则
    拘泥于《圣经》学者之研究,谓为阿拉斯河。不知阿河注里海,而黑水则必注黑海始可。又
    觅赤水不得,以《创世纪》有环绕古实之言。古实古时指非洲黑人之国,虽半岛境内亦有古
    实而必须西邻非洲或靠近红海。非洲及红海古称炎区,余以为赤水必在此等炎热之地。又以
    屈原《离骚》西行路线,系初济白水,至西极乃至流沙赤水,过此即可达于西海,乃以长仅
    二百哩流入死海即不再流之约但河当之。盖余彼时尚不知青赤白黑代表东南西北方向,竟以
    代表南方之赤水OE呏
  • 自跋一

    余去夏幸获休假,本批从事屈赋之探讨。乃忽撄胃病,更苦目昏,数月间,未览一书,
    未写一字。冬间倭氛紧急,人心惶惶,更无意于研究之事。及战局稍定,感于乱世生命之无
    保障,草木同腐之非素志,发愤取是题而写作之。武大图书馆书籍虽亦不少,然研究一专
    题,则参考材料必嫌不足,而外文方面缺乏尤甚焉。本文参考书之未举书名者为《法苑珠
    林》、《翻译名义集》,《佛教大小辞典》,丁福保《说文诂林》,北平研究院《中国地名
    大辞典》,商务印书馆《中国古今地名大辞典》,丁文江所制《中华民国新地图》,《中华
    分省本图》,童世亨所制《历代疆域形势一览图》,及坊刊中国与世界全图数种。圣经地图
    数种。因所采之书不同,故文中地名新旧不能一律。此外则为中、英、法文新旧约各一部,
    次则为。TheUniversalBibleDictionary,bytheven
    A.B.Buckland,M.A.andTheRev.A.LukynWillia
    ms,D.D(TheReligiousTractSociety,London)H
    arper’sDictionaryofClassicalLiteraturean
    dAntiquities,byHarryTnurstonPeck,M.A.F
    h.D.(AmericanBookCompa-ny,Newyork)及伦敦Geo
    rgeG,HarrapandCompanyLtd,所出原版巴比伦、埃及、希腊、印
    度神话丛书各数本而已。自去冬十二月七日起草,历时一月而脱稿,缮写修饰者又半月。而
    全文告成。嗟乎,古人著书,博览万卷,覃思十年,而余乃竟以月余之功,数十种之参考书
    籍,便思解决如此一大问题,唐突学术尊严,吾知罪矣!虽然,抗战以来,吾曹学人不啻陷
    身死海,求书既难若登天,问道又苦无其人,即再研求,所得亦不过如此。故惟有作为初
    稿,强颜付诸披露。若海内学者,不鄙其浅陋,进而教之,使昆仑之谜,终有豁然揭露之一
    朝,是则余区区发表此文之意也夫!

    三十四年一月二十五日自跋于四川乐山寓庐

    From:http://www.white-collar.net/01-author/s/15-shu-xl/yx/14.htm
  • 馀论

    夫昆仑为世界大谜,数千年于兹。余此区区考证,安敢自命已得昆仑底蕴,亦不过发其
    端绪,期与海内外学者共相商榷而已。余尝谓中国先秦历史地理,均是一篇糊涂账。古史方
    面,已有某某先生等工作多年,路线异常正确,成绩亦极其彪炳,余今日敢为此学术界之探
    险者,盖诸先生实导夫我之先路也。惟窃以为伏羲、女娲、虞舜、夏禹及夫黄帝、共工诸人
    根源,似不能完全索之故纸堆,若觅之于两河流域、埃及、波斯、印度、希腊古史与神话,
    必有惊人之发现,而我国古史整理之成功,亦可提早若干年代。一得之愚,未知整理古史者
    以为如何?地理方面,则《尚书》、《禹贡》,必系战国儒家删削外国传入之禹本纪傅合以
    中国地理而成。渤海、积石、黑水、弱水等地名,必皆彼时始有;且恐尚有无数山水名目皆
    缘《山海经》而生。若有地理学者,于古籍中考证中国地名发生之先后,则或可证实余之此
    言。若更就《山海经》而考证古两河流域地理,则亦必有重大之收获以贡献于世界焉。故以
    夏禹为中心,而中国古史问题可以解决。以昆仑为中心,而中国古代地理及中外交通史问题
    可以重新估定。以屈原《九歌》、《天问》为中心,而中国天文、地理、历法、神话及战国
    整个学术史问题亦可迎刃而解。三者并合之结论,首要者为证明“世界文化同出一源”,次
    要者证明为“中国古史混有外来神话及历史之成份”,及“战国学术思潮乃外来文化刺激所
    产生”,由是则先秦史地与文化史皆将全部改观,其关系岂不诚重且大哉!

    余兹于昆仑问题,议论暂止于此,愿就今日中国普通地理图书所谓“昆仑山脉”者,更
    一饶舌焉。今日初中学生略习地理者,叩以昆仑,亦能就地图检取新疆西藏间昆仑山脉以
    对,且谓全国诸山均发源昆仑,昆仑实为中国山祖云云。再考普通地理辞典及坊刊地图,则
    作此论调者比比皆然。有谓昆仑分中东西三支,其山脉之所延绵,不但括尽全国诸山,且渡
    海而为舟山群岛,为台湾,为日本。有谓昆仑分阴山、北岭、南岭、句漏四大山脉,亦将全
    国名山,尽隶属于昆仑系统。是盖由于历古相传“昆仑为地中央”、“昆仑为山首”之神话
    而来,实为一种地理之迷信,不可不辩。

    中国人往时虽不知昆仑究为何山,但坚信其在西北。虽无“山脉”之专词,而有山脉之
    观念。“三条四列”之说谓出《禹贡》(《禹贡》实无此明文,乃后人附会《禹贡》而
    起),其说殆甚早。唐开元间僧一行倡“山河两戒”之说(王应麟《玉海》卷二十),山脉
    之观念乃更明了。唐益《松筠龙经》之歌曰:“昆仑山是天地骨,中镇天心为巨物;如人骨
    脊与项梁,生出四支龙突兀。四支分出四世界,南北东西为四脉,西北崆峒数万程,东入三
    韩陷冥杳;惟有南龙入中国,分宗孕祖来奇特。”(《正觉楼丛书》)至明王士珍遂衍为
    “昆仑三龙”之说,谓昆仑据地之中,四旁丛山各入大荒,入中国者东南支也。其支又于塞
    外分为三支,名为北龙、中龙、南龙。亦以全国名山归之昆仑一系(见顾炎武《天下郡国利
    病书》)。魏源固主葱岭即为昆仑,遂倡“葱岭三干”之说(见《小方壶地理丛书》,魏源
    《葱岭三干考》)。唐人之说,多杂以天星分野之说及堪舆家言。明人惟言山脉而已,清人
    条理更为明晰。惟分别山脉,皆以分水线为重要根据,今日中国中小学校采为教科书之地
    图,大略皆沿袭此说。

    所谓“昆仑山脉”四字实乃外国地质学者代我所撰,此人即十九世纪初德国地质学家洪
    博德(AvonHumboladt)也。彼分亚洲山脉为四大山系,一曰阿尔泰山系,二
    曰天山系,三曰昆仑山系;四曰喜马拉雅山系。盖十七八九世纪西洋地理家言中国地理者,
    多根据中国地理书,震于昆仑之大名,不敢不为其留一位置。且按武帝定于阗某山为昆仑,
    彼中人士亦复耳熟能详,故惟有自新疆南部丛山,割取一段,强名之为“昆仑山脉”,顾自
    此而后,西洋谈中国山脉者,亦不敢竟遗昆仑。中国现代地图,本皆以欧俄日本所制者为蓝
    本,自是而昆仑山脉之在后藏新疆,俨然成为定案矣。夫山脉之名,无非随人而定,设全国
    诸山果皆导源昆仑山脉,吾人亦何妨竟认昆仑为中国山祖。然今昆仑山脉实分自葱岭,葱岭
    高度又远过昆仑,吾人不祖葱岭而祖昆仑,果有何等理由乎?且根据地质学定理:山脉之成
    因有所谓“剧烈褶曲”者焉,有所谓“拗褶”者焉,有所谓“断层”者焉,有所谓“火山喷
    发”者焉,有所谓“侵蚀作用”者焉,而分水线则殊不关重要。山之质素与构成之年代相同
    者乃可为一脉,否则不能强一之也(以上皆引自《中国山脉考》,《科学》第九卷第九
    期)。中国山脉,究有几系,今日尚未完全考定,要之非皆导源昆仑,则可断言。且“山
    脉”(Orography)之语,今日地理学家已置诸不论之列,而中国言地理者,至今
    犹以“山脉”二字津津挂诸齿颊,且信全国诸山出于昆仑山脉之说,不太缺乏现代地质常识
    欤?昆仑神话,今已无人肯信,而昆仑山脉之迷信又起而代之,诚不知昆仑之魔力何以竟如
    斯之巨也!余深愿我国地理学家,以后制图立论,于此谬说,必须力加纠正。而彼盈千累万
    之坊刊地图,各校采为教
  • 六昆仑与中国

    我国自称“中国”,盖闭关时代,本部与四裔相对待之名词。顾此语亦受两河文化影
    响。今日西亚楔形文字发现于地底者,尚不见自称其国为“中国”之语。然观乎昆仑号为地
    中央,及冀州齐州之号为中国,吾知“中国”一词亦来自西亚矣。今请观《淮南·地形
    训》:“昆仑之丘,或上倍之,是谓凉风之山,登之不死。或上倍之,是谓悬圃,登之乃
    灵,能使风雨。或上倍之,乃维上天,登之乃神,是谓太帝之居。扶木在阳州,日之所罢。
    建木在都广,众帝所自上下,日中无景,呼而无响,盖天地之中也。”

    《河图·括地象》:

    “地中央曰昆仑……”

    “昆仑之墟下洞,含有赤县之州,是为中则。”

    “昆仑山为柱、气上通天。昆仑者地之中也。”“昆仑居地之中,其势四下,名山大
    川,皆有气相承接。”“昆仑地之中也,其外有五色弱水,横绕三千里,深十三寻。”

    次则请究“冀州”、“齐州”。中国所谓九州者,自《禹贡》(宋王应麟《玉海》,古
    帝如伏羲等亦有分州之说,当然不足取)。禹所分者为冀、兖、青、徐、扬、荆、豫、梁、
    雍九州。《尔雅·释地》,则为冀、豫、雝、荆、扬、兖、徐、幽、营等九州。《周礼·夏
    官·司马》所分为扬、荆、豫、青、兖、雍、幽、冀、并等九州。此三书皆中国之经书,代
    表正统文化者也,而其所记九州之名,便已不能一致。然此尚可推诿为夏商周三代制度有
    异,故州名亦不同。至《淮南·地形训》及纬书之九州,名目与经书亦有参差。《地形
    训》:“何谓九州:东南神州曰农土,正南次州曰沃土,西南戎州曰滔土,正西吉廾州曰并
    土,正中冀州曰中土,西北台州曰肥土,正北
  • 五昆仑与四河

    昆仑构成之条件,珍木异兽,琼楼玉宇,仙灵神怪等等尚非重要,重要者厥维发源昆仑
    而各自流入大海之四条大河。此为探讨昆仑所在地之关键,而亦笔者此文研究之中心也。希
    腊奥林匹司山实际无河,OE吅佑谮そ缫酝猓
  • (A)神话的昆仑

    (一)昆仑神话之来源原人初能运用思考能力时,幻想至为丰富。彼仰视天空,见其广
    大无垠,高不可攀,以为必有一种超越吾人之种类,居于其间,名曰神明,或曰精灵。其能
    力至为伟大,且又青春永驻,长生不死。顾其形体及其感情意志,则亦同乎吾人。人类之宗
    教心理,固要求神之与人相通,故有人神同形说,天人交感说,转劫说之发生;原人思想简
    单,则又想象天神必常居地面,以便与凡人接触,是以建立庙宇及神坛,以为神明税驾之
    所。然神固不能长溷凡尘,则又想像崇高之山岭,为神地面之栖止处。我国有僊仙二字,仙
    字,从山从人,像人在山上。见《说文》。《韵会》:“仙,轻举也:从人在山上。”《玉
    篇》:“仙,轻举貌,人在山上也。”至僊字,从人迁声,《诗·小雅·宾之初筵》:“屡
    舞僊僊。”《庄子·有宥》:“僊僊乎归矣。”成玄英曰轻举貌,实与神仙之仙无涉。后人
    以其同音以代仙字。《说文》轻举之义,当由僊字来。实则仙字之义,非轻举所能括,以人
    在山上为主。仙字之产生或在战国时代,域外文化大入之时。后世道家有三十六洞天之说,
    以海内之名山,为神仙之洞府,尚系人在山上观念之衍化。希腊称神为“奥林匹司人”或
    “居于奥林匹司者”(Olympian)。印度古神话,诸神亦居山上。喜马拉雅山则为
    神人常居之地。凡思登天者,须登此山。特山为万神之王因陀罗所主,每以疾雷暴风雨阻止
    登山之人,故能登者罕。其后衍为须弥山神话,此山乃为得道者超凡入圣之阶云。

    关于昆仑仙山之想象,不知始于何时,今日文献之约略可徵者,惟有文化最早之两河流
    域,故吾人亦惟有姑定两河流域为昆仑之发源地。考西亚远古传说,即谓有一仗山曰Khu
    rsagKurku-ra,其义犹云“大地唯一之山”(MountainofAllL
    ands)或曰“世界之山”(MountainoftheWorld),为诸神聚居之
    处,亦即诸神之诞生地(Thebirthplaceofthegods)。关于此山详
    细之描绘,今日西亚出土之砖文,尚无可徵,良堪惋惜——吾人愿望之满足,或将待之他日
    地底文化资料之发现而已。但西亚若干庙宇与七星坛之建筑,皆为此山之缩型。而中国之昆
    仑,希腊之奥林匹司,印度之苏迷卢,天方之天园,亦为此山之翻版。吾人根据此类材料,
    以揣测“世界大山”之景况,亦未尝不可十得八九,此则吾人尚可引为差堪自慰之事者也。

    笔者固不解西亚语文,以意测之,Khursag之一字或指“世界”,或指“大
    地”,而Kurkura之一字则或为“大山”,为“高山”。中国之昆仑,古书皆作昆
    仑。说文谓昆为古浑切,仑,卢昆切。以今日粤音读之,与Kuhura相差不远,殆音译
    其后一字也(且此仙山实为阿拉拉持(Ararat),波斯人呼阿拉拉持山为Kuh-i
    -nuh则音与昆仑更近)。夫西亚与中国古代之语音,一则几经转译,一则屡有变迁,而
    尚能保存此项对音,使昆仑之真源不昧,终能互证于数千年后之今日,此则非可喜可庆之事
    耶?

    (二)昆仑神话之分布西亚仙山神话分布之广,几遍全世界。埃及相传亦有大山,为群
    神诞生及聚居之所,惜今亦莫考厥详。至菲里士坦人之喀密(Carmel),希腊人之奥
    林匹司(Olympus),北欧人之阿司卡德(Asgard),印度人之苏迷卢(Su
    menu),殆无不由西亚“世界大山”之演化。(1)希腊之奥林匹司希腊人所想象此仙
    山之景况,考之荷马史诗《依里亚德》及《奥德赛》,再考之希腊诸神话,则亦殊为奇丽。
    大概谓:此山最高处为天帝宙士(Zeus)所居。宙士召集群神会议亦在其处。有云母石
    之宫殿,宏峻无比。殿中梁柱,巨壮异常,瑰采琦光,互相映发;所有宝座,皆黄金白银所
    成。宙士高踞中央之座,称为天地万物之主宰,亦称为诸神之父,万神之王。其他诸神,则
    各按其品级之高下,列坐于两旁。宫廷四壁,铺满凡手不能描绘之图画,谲诡奇幻,万态千
    形。其色则或浅绛,或殷红,或金黄,或深紫,瞣e皇绚丽,炫人心目,有似夕照西沉时之
    一天霞彩∩结燮
  • 三中国境内外之昆仑

    史言汉武帝定昆仑,而昆仑究为于阗何山,则史无明文,历来亦无确指。近代始有学者
    加以考求,而其结论则亦未必正确。此非吾国人研究学问不求甚解之态度为之害也。盖清以
    前西域未归版图,道路又绝窎远艰阻,勘察为难也。唐元清三代皆有事于西域,而昆仑之所
    在,乃大成问题,其故可知矣。且昆仑本不在中土,无其地而强指一山以名之,则人之意见
    必不能尽同,于是昆仑乃成为任人呼唤,信手成采之枭卢,此神秘之仙山,竟随地涌现焉。
    又有印度传来之神话,海外国族之同音,映射缠纠于其间,更使吾国之谈昆仑者,有耳乱八
    音,目迷五色之概,昆仑问题之成为中国地理上之大谜,盖由于此,今吾人若企图解决此
    谜,则必须将历来昆仑所蒙之面纱,层层剥去,而后昆仑之真相可得。故吾人不得不再翻昆
    仑档案,计算中国境内外,究有若干昆仑。(A)中国境内之昆仑清以前,中国本部之昆
    仑,则有安徽潜山县东北六十里之一山,福建惠安县东北三十里之一山。广西邕宁东北一百
    二十里之一山,而广西昆仑山上之昆仑关为宋狄青元夜破依智高处,亦抗战以来,常见于报
    章之要塞也。顾此皆为昆仑之模制品,一望可知,素亦无人措意,故余对此亦不愿再言,今
    则言昆仑之在中国西部者。不问考定时代之后先,拟议之人之贵贱,但以地段由东向西之顺
    序为断。

    (一)在青海西宁《汉书·地理志》:“金城郡临羌,西北塞外,有西王母石室,西有
    弱水,昆仑山祠。”临羌者汉置临羌县,赵充国曾于此屯田。今为青海省会。城濒湟水南
    岸,青海额鲁特蒙古及阿里克等四十姓土司,与汉人互市于此。为西边一大都会。临羌之
    地,原为羌人所居,后慕汉威德,愿献地内属。王充《论衡·恢国》篇:“孝平元始四年
    (公元四年)金城塞外羌献其鱼盐之地,愿内属,汉遂得西王母石室,因以为西海郡。”郑
    玄注《禹贡》之织皮昆仑,谓为西方之戎人,马融则谓昆仑在临羌西,盖为种族之名。汉志
    仅言西王母、弱水、昆仑祠,而未尝言其地有何山足称为昆仑。然境内既有弱水,则亦必有
    一小山名为昆仑者在,西王母石室当即建此山上,故汉志名之曰“山祠。”

    (二)在敦煌《汉书·地理志》:“敦煌郡广至,有昆仑障。”塞外险要之处,可筑防
    御工事者,皆以障名。《史记》“筑亭障以逐戎人。”《汉书》“又出五原塞数百里,远者
    千里,置城障,列亭”可证。必山岳丘陵乃足称为险要,故敦煌之昆仑障,料亦必筑于山陵
    之上。此山即名为昆仑者是也。(三)在酒泉崔鸿《十六国春秋·前凉录》:“酒泉太守马
    岌上言,酒泉南山,即昆仑之体也。周穆王见西王母,乐而忘归,即在此山。山有石室王母
    堂,珠玑镂饰,焕若神宫”(《史记集解》及《太平御览》引)。

    (四)即阿尼马卿山《禹贡》:“道河积石,”盖本之《山海经·海内西经》:“河水
    出东北隅……入禹所导积石山。”中国遂以黄河重源再出处,指一山名之为积石。积石有大
    小,小积石在今甘肃临夏县西北,即唐述山,当黄河曲处,其地有积石关;大积石则在今青
    海东南境,番名阿木奈玛勒占木逊山,又曰阿弥耶玛勒津木逊山,又曰阿木尼麻禅母逊阿
    林。蒙古语则曰木素鄂拉。今地理书则作阿尼马卿山。刘元鼎使吐番谓得河源于莫贺延碛
    尾,曰闷摩黎山,即此山也,闷摩黎盖与阿木奈,阿弥耶、阿木尼为对音,特吞其尾音耳,
    黄河发源星宿海,流入札陵、鄂陵两湖,又数百里,至阿尼马卿山西部,容纳一河;又蜿蜒
    曲折行数百里,抵山之腹部,纳一河流;沿山东南行,至棱宗贡巴,陡折而北,于是行于西
    倾及阿尼马谷中,凡入六七河,其出于阿尼马北者三焉。刘元鼎探河源仅至于此,遂以为黄
    河发源于此山,而名之为昆仑。然此亦非刘元鼎之误,恐其受蕃人之欺骗而已。盖阿尼马卿
    高达海拔六千公尺左右,实为吐蕃境内之圣山。徐松言西蕃语谓“阿弥耶”为众山之祖
    (《西域水道记》卷二)。则西番人盖视之为群山之祖,恰值此山又有数河注入黄河,乃对
    中国人自炫为昆仑。元鼎不察,信以为真,遂有此误。

    元代都什所觅得河源以东之大雪山,亦即阿尼马卿也。《元史·地理志·河源附录》,
    谓大雪山在朵甘斯之东北。按元置朵甘思宣慰司以统蕃羌。青海之东南至西康之境,皆其
    地。今阿尼马卿山在青海东南,西康西北,则地望恰合。都什之报告录,谓“山腹至顶皆
    雪,冬夏不消”,朱思本所译之帝师梵文记录,谓“此山高峻非常,山麓绵亘五百余里。黄
    河随山足东流,过萨斯嘉库济克持地,”均与阿尼马卿情况相合。然元人似不知其所得之亦
    耳麻不莫刺山,即刘元鼎所得之闷摩黎山。清人亦似不知元人所得之亦耳麻不莫刺,即其常
    所称道之阿木奈玛勒占木逊。如魏源、徐松皆以为两山是也。(徐松在其《西域·水道记》
    卷三中言:“大积石在克俦渡口,距阿弥耶玛勒津木逊山一千六百里,”在其《汉书·西域
    传补注》中,则又谓:“河……经阿木奈玛勒占未逊山南麓,即大积石山,”一人之言而自
    相矛盾至此,不亦可怪欤?)(五)即巴颜喀喇山清圣祖尝遣使穷河源,以其时西藏未归版
    图,仅至青海星宿海而止,遂以巴颜喀
  • 二汉武帝考定昆仑公案

    汉武帝为我国历史上有名勤远略之帝王,亦迷信神仙最甚之帝王也。彼以欲断匈奴右臂
    之故,遣张骞使月氏。为匈奴所遮,而至大宛,遂得知河源形况。《史记·大宛列传》云:
    “于阗之西,则水皆西流注西海。其东,水东流注盐泽。盐泽潜行地下,其南则河源出焉。
    多玉石,河注中国……而汉使穷河源。河源出于阗,其山多玉石采来(按《史记》集解:瓒
    曰,‘汉使采取将来持至汉。’张文虎校《史记》札记则云:‘采来二字,连上为句。采当
    为采色之采。来乃
  • 一昆仑一词何时始见于中国载记

    问昆仑一词果于何时开始见于我国古籍,则颇不易考定,盖我国最初文献,已无可征,
    而地底文化资料,则尚未完全发见。今日出土之甲骨铜器文字,其中似尚无昆仑字样。至于
    普通古书,则《夏书·禹贡》有:“织皮昆仑、析支、渠、搜、西戎即叙。”

    若《禹贡》果为大禹治平洪水以后,令其臣曰伯益者所作,则昆仑一词,夏初即见于中
    国文籍矣。但据历来学者考证,《禹贡》地理有秦汉以后之名。近代学者曾断定此文乃战国
    时产品。况本文昆仑一词,据郑玄注“衣皮之民,居此昆仑、析支、渠搜三山之野者,皆西
    戎也”(《尚书正义》疏引)。又谓“别有昆仑之山,非河所出者也”(同书)。孔颖达则
    谓渠与搜为二国,郑误一之。四国皆衣皮毛,故以织皮冠之。昆仑也,析支也,渠也,搜
    也,四国皆是戎狄,故末以西戎总之云云(同书)。蒋廷锡云“西戎国盖附近昆仑山者,郑
    康成云‘衣皮之民,居此昆仑、析支、渠搜三山之野者’是:昆仑、析支、渠搜皆本山名,
    而用以为国号者也”(《皇清经解》,蒋相国《尚书地理今释》)。笔者按:清圣祖尝令人
    穷河源,初定巴颜喀喇山为昆仑,继定冈底斯。圣祖于其御批《通鉴纲目》云:“昆仑国
    名,昆仑山旁小国也;今西北别有昆仑都国,去中国甚远。”蒋氏《尚书地理今释》多采当
    时由实地调查得来之记录,故其注禹贡昆仑,亦曾采用巴颜喀喇山之说,其曰戎国盖附近昆
    仑山者云云,殆采取圣祖意见也。

    近人卫聚贤先生谓织皮昆仑之昆仑即《左传》陆浑之戎(见《说文月刊》第一卷第九
    期,吕思勉《西王母考附录》),丁山先生亦谓汉之乌孙、昆莫、即陆浑之音转,而陆浑即
    昆仑之音转,其说恐本之卫氏,而考证则更加精详(见《说文月刊》第四卷合订本,《论炎
    帝大岳与昆仑山》),若此,则禹贡之昆仑,非地名,与本文主题无涉,此一份昆仑案卷惟
    有搁置一旁,本文以后虽偶涉及,亦不作主要论题。其次,则《尔雅》颇多昆仑字样:《释
    地》:“西北之