博客首页|TW首页| 同事录|业界社区
2010-10-28

话说商场如战场,虽然见不到战火硝烟的场景,但总能让人闻到硝烟的味道。网游!一个生存于互联网大环境下的爆炸点,它有着几大特性:

1、 快速发展的产品规模——包括:产品收入、就业人员、产品上线规模等等

2、 市场竞争已白日化——做蛋糕的速度远远没有吃蛋糕增长的快

3、 年轻,容易浮躁——网游行业年轻,做网游的人年轻,年轻往往容易浮躁

网游从诞生到现在,竞争一直存在,但是以前的竞争相对还是平缓的进行着,到了2010年,网游竞争被摆到台面上了。从年初各大上市公司的人才争夺战,到年末的用户争夺战,以及海外游戏代理之争,无处不弥漫着战火硝烟,与此同时,让人更意想不到的是网游公司内部斗争也开始慢慢显露。

下面我们从最近的斗争慢慢的往前写,带着大家一起回顾下2010年发生在我们身边的那些事。

一、 杯具之争,部门之争伤人伤己

当大家都还在谈论九城《神仙传》发布会和7仙女的时候,天雷滚滚,有消息称“九城内斗市场部弃《神仙传》保《三国群英传2》”,而且微博、媒体等也纷纷发表了相关的稿件,这其中还不缺有理证据:

此事微博上的传播

事非偶然,当阿飞说道:像久游那样,市场中心就是背黑锅的孙子吗?这一句话又道出了另一则故事,那就是久游《神兵传奇》开始是雄赳赳气昂昂的进军,到最后一脸无奈的惨败。辉煌的百度指数、有影响力的谢霆锋代言和新闻发布会、各种媒体的广告投放,已经形成了网络和地面、资讯和娱乐的完美结合,宣传攻势可谓不一般,但最后的结果依然是失败,谁之过?

俗话说,家丑不外扬,无论是九城的《神仙传》,还是久游的《神兵传奇》,他们的家丑却成了业界的谈资和媒体的新闻素材,有失风化,有失风化。当游戏公司内部出现矛盾的时候,内部矛盾是不是应该消化在无形之中。当我们再一次回忆起,朱骏痛失《魔兽世界》后的豪言壮志和不差钱的冷幽默,以及久游砸1亿元做《神兵传奇》时的气吞山河,然后结合上面的现实,总让人感觉有点哭笑不得。

当内部矛盾还未解决的时候,你如何能集中所有火力对外呢?九城和久游这两事件,是业界的教训,也是年轻人浮躁的一种表现。

现在游戏行业已经不再是几年前,用点钱就能砸出同时在线的,也不是靠一个明星就能支撑你一款游戏的,而是需要整个团队的合作,这其中包括了:研发、产品运营、市场宣传、安全维护、客户服务等一体化的服务于用户、服务于媒体,将问题解决在无形中,这才真正是产品运营的根基,也是产品成功的关键所在。游戏公司内部斗争,是伤己的行为,是内伤,需要长期调理,而非外科手术能医治的。

久游《神兵传奇》内部会议

二、 创意无限,市场营销之争

大家每天吃同样的东西,肯定会感觉到厌烦,网游市场营销也是如此,当玩家每天看到同样的内容、同样的话题,慢慢的就会感觉到疲劳,这其中包括审美疲劳、视觉疲劳等,其实有一个现象很能说明这一道理:当“门”这个字出现在网络上的时候,大家都十分的关注,然而,现在再出一个“XX门”,你还会点进去看吗?

网游营销就是将需要宣传的产品内容进行包装,用时尚的、有关注点的、有话题等等人或物关联起来,达到宣传的目的。很多网游人士都在谈论,现在网游营销是越来越难做了。当前网游宣传点击量最高的无非是:标题党、低俗、恶搞、美女等,当然真正精品也是可以获得认同的,但付出的时间和金钱代价太高了。

当网络上出现一种热点内容的时候,所有网游策划团队,都将眼睛睁的大大的。如当时的凡客体:

相信看这篇稿子的人,相信都有这样的经历,当笔者这里首次看到的时候,一种无比新奇的眼观看完所有内容,而且也非常乐于去传播,酷似老子发现新大陆,迫不及待的跟朋友分享。然而接踵而至的是,所有网游公司都将自己的NPC、道具、代言人等等都植入其中,变成了一种商业宣传,此时,笔者也失去了看凡客体的乐趣。

真人出镜,的确是也是无奈之举了。因为美女、低俗等等各种方式方法都已经漫天飞的时候,《聊个斋》出了真人教学视频,这其实也看出了网络营销的无奈。当没了创意,没了想法的时候,那只有在各种数字上做文章了,各种数字游戏就大胆的登堂入室。

在我们这些穷的叮当响的人来说,这千万、上亿都已经是天文数字了,那些网游老板们,一个小活动就拿出上千万,让笔者无比的蛋疼,死的心都快有了。世界为啥这样的不公平,老板们有那么多钱,还每天想着吸收更多的钱,穷的我们只盼望有自己的一处住所也变成一种奢望。

三、 海外资源掠夺

用这个小标题,很多人会说,是不是夸张了点,用掠夺!笔者认为一点也不夸张,中国网游对海外市场、海外游戏产品、研发人才、运营公司等等,从来都是用抢的,无论代价多大,先抢过来再说。

如果把网游运营公司比成前方打仗的部队,那研发公司就是后续的补给(粮草、军械库等等),懂兵法的人都明白,后援补给对于一场战争的胜负影响有多大。这点,中国各大上市公司都明白,他们在2010年大出血,收购海外公司来增加自己后防的补给线。

3月份,完美时空对外宣布2100万美金全资收购日本游戏C&C Media公司;

盛大游戏用8000万美元包括6000万美元和2000万美元股权,收购麻吉传媒(旗下有15000多款网游游戏);

盛大网游以9500万美元收购《龙之谷》开放商Eyedentity Games

等等等等等

除了海外游戏公司,还有最直接的一块内容,就是海外产品。2010年最关注的一款游戏代理是——《七龙珠》,从最早代理权在国内闹得沸沸洋洋,其中代理之争的有:盛大网游、腾讯网络、研祥集团等。如此一款游戏汇聚了,游戏大亨、即时通讯大亨、智能科技款爷的数次交手,这里就不说最后谁胜谁败,但笔者认为《七龙珠》韩国开放公司,绝对是胜者。

当更多游戏公司上市,操作资本原作时;当国内网游市场竞争更加激烈时;当更多其他行业巨鳄窥视进入时,网游市场的代理、收购之争会愈演愈烈。良性的竞争有利于市场规范化成长,但出现恶性的竞争时,市场将会天崩地裂。

四、 人之根本,才人之争

2010年7月中旬,中国互联网络信息中心发布了《第26次中国互联网络发展状况统计报告》显示,截至2010年6月,我国网游人才缺口进一步扩大,据不完全统计,目前中国动漫网游人才缺口达30万。

网游之争,归根结底,还是落实到人才竞争。从打工皇帝唐骏脱离盛大,到“造假门”事件,都说明了一个问题,学历、人才,以及人才难留的问题。这些现象特别是在各大网游巨头表现的最为明显。

其中争夺最为厉害的有:盛大、畅游、腾讯、巨人

盛大针对人才吸引和挽留提出“风云计划”、“18计划”、“20计划”等等,盛大在线还推出了“百万悬赏”计划,这些全部是为了招兵买马。

巨人网络在人才这块上也推出了“赢在巨人”计划,吸引海内外优秀人才。同时畅游、腾讯等他们都对人才这块拿出了自己的妙招。网游人才缺少的时代,各大公司高薪挖角成了必然。这其中不光是单个优秀人才,还包括研发团体。人才永远是不变的话题,然而要留住人才,笔者认为,要留住人,不光是给多少钱、多少股份的问题。因为真正优秀的游戏人才,他们在哪里都能得到高收入,被挖角一次也不过是增加一些,对他们总资产来说变化不大,主要的问题还是在于向心力、共同目标。但人才和公司、领导、环境出现问题的话,再好的诱惑也会被拒之门外,所以留人攻心为上。

五、 不差钱明星代言之争

咱不差钱,差的只是人气,这是网游公司的一个写照。明星代言一直以来是网游行业宣传的一个要点,也可以说是最直接、最省事的营销手段。网游行业从性质上来看,可以归属于文化娱乐产业,演艺明星的加入更是增加了这娱乐氛围。网游公司真的不差钱,找明星代言各个是代价不菲。《梦幻西游》请的周杰伦,到《神兵传奇》的谢霆锋,然后还有《醉逍遥》的古天乐、《大唐无双》的甄子丹、以及最近代言的网游的成龙,哪个不是有头有脸的人物,一个咳嗽都能引发粉丝咆哮的。

奇怪!奇怪,真的很奇怪,今年网游代言的打牌全部是男明星。不差钱,只能说是在游戏宣传的时候,明星代言,当然最求的是明星代言的最大效果,这效果其实就是对游戏品牌宣传带来多少,这其中包括了:广告素材、活动噱头、娱乐传播等等。在各大网游厂家纷纷争斗各大娱乐明星的时候,是否真正做到了,将明星代言做到宣传最大化。难道真的一句话:不差钱,就只是代言做做广告素材,再开一个新闻发布会足以。扯蛋!明星带来的是吸引眼球、吸引关注,如果没有资源最大化的利用,那明星代言仅仅是游戏公司市场部无奈营销的一种被逼。

笔者最近有点蛋疼,也好久没写稿件了,以上内容都是笔者在2010年到今所感受到的,而且也有很多是自己有所经历过的。竞争无所不再,特别是快速发展的网游行业,特别的残酷,特别的无情。不进则退,这是网游生存法则,也是网游人的生存法则,切记浮躁、骚动,安心建立团队目标,树立公司规划,产品定位以及分析,我想再残酷的竞争都可以坦然处之、微笑面对。

转载于游戏鬼才的新浪博客

2010-10-26

  编写高效简洁的C语言代码,是许多软件工程师追求的目标。本文就是针对编程工作中的一些体会和经验做相关的阐述。

  第一招:以空间换时间

  计算机程序中最大的矛盾是空间和时间的矛盾,那么,从这个角度出发逆向思维来考虑程序的效率问题,我们就有了解决问题的第1招–以空间换时间。比如说字符串的赋值:

  方法A:通常的办法

  #define LEN 32

  char string1 [LEN];

  memset (string1,0,LEN);

  strcpy (string1,”This is a example!!”);

  方法B:

  const char string2[LEN] =”This is a example!”;

  char * cp;

  cp = string2 ;

  使用的时候可以直接用指针来操作。

  从上面的例子可以看出,A和B的效率是不能比的。在同样的存储空间下,B直接使用指针就可以操作了,而A需要调用两个字符函数才能完成。B的缺点在于灵活性没有A好。在需要频繁更改一个字符串内容的时候,A具有更好的灵活性;如果采用方法B,则需要预存许多字符串,虽然占用了大量的内存,但是获得了程序执行的高效率。

  如果系统的实时性要求很高,内存还有一些,那我推荐你使用该招数。该招数的变招–使用宏函数而不是函数。举例如下:

  方法C:

  #define bwMCDR2_ADDRESS 4

  #define bsMCDR2_ADDRESS 17

  int BIT_MASK(int __bf)

  {

  return ((1U << (bw ## __bf)) - 1)<< (bs ## __bf);

  }

  void SET_BITS(int __dst,

  int __bf, int __val)

  {

  __dst = ((__dst) & ~(BIT_MASK(__bf))) |

  \

  (((__val) << (bs ## __bf))

  & (BIT_MASK(__bf))))

  }

  SET_BITS(MCDR2, MCDR2_ADDRESS,RegisterNumber);

  方法D:

  #define bwMCDR2_ADDRESS 4

  #define bsMCDR2_ADDRESS 17

  #define bmMCDR2_ADDRESS BIT_MASK(MCDR2_ADDRESS)

  #define BIT_MASK(__bf)

  (((1U << (bw ## __bf)) - 1)

  << (bs ## __bf))

  #define SET_BITS(__dst, __bf, __val)

  \

  ((__dst) = ((__dst) & ~(BIT_MASK(__bf)))

  | \

  (((__val) << (bs ## __bf))

  & (BIT_MASK(__bf))))

  SET_BITS(MCDR2, MCDR2_ADDRESS,

  RegisterNumber);

  函数和宏函数的区别就在于,宏函数占用了大量的空间,而函数占用了时间。大家要知道的是,函数调用是要使用系统的栈来保存数据的,如果编译器里有栈检查选项,一般在函数的头会嵌入一些汇编语句对当前栈进行检查;同时,CPU也要在函数调用时保存和恢复当前的现场,进行压栈和弹栈操作,所以,函数调用需要一些CPU时间。

  而宏函数不存在这个问题。宏函数仅仅作为预先写好的代码嵌入到当前程序,不会产生函数调用,所以仅仅是占用了空间,在频繁调用同一个宏函数的时候,该现象尤其突出。

  D方法是我看到的最好的置位操作函数,是ARM公司源码的一部分,在短短的三行内实现了很多功能,几乎涵盖了所有的位操作功能。C方法是其变体,其中滋味还需大家仔细体会。

  第二招:数学方法解决问题

  现在我们演绎高效C语言编写的第二招–采用数学方法来解决问题。数学是计算机之母,没有数学的依据和基础,就没有计算机的发展,所以在编写程序的时候,采用一些数学方法会对程序的执行效率有数量级的提高。举例如下,求 1~100的和。

  方法E:

  int I , j;

  for (I = 1 ;I<=100; I ++)

  {

  j += I;

  }

  方法F

  int I;

  I = (100 * (1+100)) / 2

  这个例子是我印象最深的一个数学用例,是我的计算机启蒙老师考我的。当时我只有小学三年级,可惜我当时不知道用公式 N×(N+1)/ 2 来解决这个问题。方法E循环了100次才解决问题,也就是说最少用了100个赋值,100个判断,200个加法(I和j);而方法F仅仅用了1个加法,1次乘法,1次除法。效果自然不言而喻。所以,现在我在编程序的时候,更多的是动脑筋找规律,最大限度地发挥数学的威力来提高程序运行的效率。

  第三招:使用位操作

  实现高效的C语言编写的第三招——使用位操作。减少除法和取模的运算。在计算机程序中数据的位是可以操作的最小数据单位,理论上可以用”位运算”来完成所有的运算和操作。一般的位操作是用来控制硬件的,或者做数据变换使用,但是,灵活的位操作可以有效地提高程序运行的效率。举例如下:

  方法G

  int I,J;

  I = 257 /8;

  J = 456 % 32;

  方法H

  int I,J;

  I = 257 >>3;

  J = 456 - (456 >> 4 << 4);

  在字面上好像H比G麻烦了好多,但是,仔细查看产生的汇编代码就会明白,方法G调用了基本的取模函数和除法函数,既有函数调用,还有很多汇编代码和寄存器参与运算;而方法H则仅仅是几句相关的汇编,代码更简洁,效率更高。当然,由于编译器的不同,可能效率的差距不大,但是,以我目前遇到的MS C ,ARM C 来看,效率的差距还是不小。相关汇编代码就不在这里列举了。

  运用这招需要注意的是,因为CPU的不同而产生的问题。比如说,在PC上用这招编写的程序,并在PC上调试通过,在移植到一个16位机平台上的时候,可能会产生代码隐患。所以只有在一定技术进阶的基础下才可以使用这招。

  第四招:汇编嵌入

  高效C语言编程的必杀技,第四招——嵌入汇编。”在熟悉汇编语言的人眼里,C语言编写的程序都是垃圾”。这种说法虽然偏激了一些,但是却有它的道理。汇编语言是效率最高的计算机语言,但是,不可能靠着它来写一个操作系统吧?所以,为了获得程序的高效率,我们只好采用变通的方法–嵌入汇编,混合编程。举例如下,将数组一赋值给数组二,要求每一字节都相符。

  char string1[1024],string2[1024];

  方法I

  int I;

  for (I =0 ;I<1024;I++)

  *(string2 + I) = *(string1 + I)

  方法J

  #ifdef _PC_

  int I;

  for (I =0 ;I<1024;I++)

  *(string2 + I) = *(string1 + I);

  #else

  #ifdef _ARM_

  __asm

  {

  MOV R0,string1

  MOV R1,string2

  MOV R2,#0

  loop:

  LDMIA R0!, [R3-R11]

  STMIA R1!, [R3-R11]

  ADD R2,R2,#8

  CMP R2, #400

  BNE loop

  }

  #endif

  方法I是最常见的方法,使用了1024次循环;方法J则根据平台不同做了区分,在ARM平台下,用嵌入汇编仅用128次循环就完成了同样的操作。这里有朋友会说,为什么不用标准的内存拷贝函数呢?这是因为在源数据里可能含有数据为0的字节,这样的话,标准库函数会提前结束而不会完成我们要求的操作。这个例程典型应用于LCD数据的拷贝过程。根据不同的CPU,熟练使用相应的嵌入汇编,可以大大提高程序执行的效率。

  虽然是必杀技,但是如果轻易使用会付出惨重的代价。这是因为,使用了嵌入汇编,便限制了程序的可移植性,使程序在不同平台移植的过程中,卧虎藏龙,险象环生!同时该招数也与现代软件工程的思想相违背,只有在迫不得已的情况下才可以采用。

2010-10-22

  休眠的步骤

  将一个进程置于休眠状态,一般步骤如下:

  0. 定义并初始化(如果还没有的话)一个等待队列头(wait_queue_head_t),这个等待队列头应该是能被要休眠的进程和负责唤醒的进程都能访问到。

  1. 对进程的每次休眠,定义并初始化一个等待队列(wait_queue_t)

  2. 把等待队列加入到相应的等待队列头中。

  3. 把进程状态置为 TASK_INTERRUPTIBLE 或 TASK_UNINTERRUPTIBLE

  4. 再次检查休眠条件是否为真,否则跳过第5步

  5. 执行 schedule()

  6. 清理:将进程状态改为 TASK_RUNNING(通常已经是,除非是从第4步跳过来的),把等待队列从等待队列头中删除(防止多次唤醒)

  7. 如果是可中断休眠的话(TASK_INTERRUPTIBLE),检查是否是因信号而被唤醒。如果是的话,一般直接 return -ERESTARTSYS 让上层处理。

  8. 检查需要等待的条件是否满足,如果不是的话,再回到第1步重新开始。

  注意,第4步的检查条件非常重要。因为到第3步之前,条件可能已被满足,而如果我们再把进程状态设为 TASK_INTERRUPTIBLE 或 TASK_UNINTERRUPTIBLE ,直接执行 schedule() 的话就可能再也无法被调度到。但如果条件是在第4步到第5步之间满足的话,那不用担心,因为既然条件能满足,就应该有唤醒,而我们的进程状态应该又被设为了 TASK_RUNNING,所以 schedule() 会调度到我们。

  另外,以上只是一个一般的步骤,具体休眠时可根据个人的理解和实际的需要灵活调整。

  内核提供的操作方法

  根据上面的步骤,内核提供了至少两种方法来帮助实现,我把他们称作是半自动DIY式的和全自动傻瓜式。

  半自动DIY式

  wait_queue_head_t wq; init_waitqueue_head(&wq); –对应第0步

  DEFINE_WAIT(wait); –对应第1步

  prepare_to_wait(&wq, &wait, TASK_INTERRUPTIBLE); –对应第2,3步

  if (condition) schedule(); –对应第4,5步

  finish_wait(&wq, &wait); –对应第6步

  if (signal_pending(current)) return -ERESTARTSYS; –对应第7步

  全自动傻瓜式

  wait_queue_head_t wq; init_waitqueue_head(&wq); –对应第0步

  int ret = wait_event_interruptible(wq, condition); –对应第1,2,3,4,5,6步和第7步前半步

  if (ret != 0) return -ERESTARTSYS; –对应第7步后半步

  如果看内核代码的话,就可以发现wait_event系列其实就是对第1,2,3,4,5,6,7步的一个宏包装

  唤醒

  唤醒的操作相对简单,就用 wake_up 系列函数。比如 wake_up_interruptible(&wq),它会把等待队列头(wq)上的所有进程都去唤醒。

  实现细节

  关于休眠的内核实现细节,其实半自动DIY式的每一步所做的事都对应相应的休眠步骤中所描述的,只有第1步中初始化一个等待队列 (wait_queue_t)的概念比较模糊。

  先看一下一个等待队列(wait_queue_t)的数据结构:

  struct __wait_queue {

  unsigned int flags;

  #define WQ_FLAG_EXCLUSIVE 0×01

  void *private;

  wait_queue_func_t func;

  struct list_head task_list;

  };

  typedef struct __wait_queue wait_queue_t;

  再看一下 DEFINE_WAIT 的宏定义:

  #define DEFINE_WAIT(name) \

  wait_queue_t name = { \

  .private = current, \

  .func = autoremove_wake_function, \

  .task_list = LIST_HEAD_INIT((name).task_list), \

  }

  由此可见,private 字段被指向了当前进程,func字段是一个函数指针,当内核要唤醒一个等待队列时,内核就会调用 func 所指向的函数来唤醒进程,而 autoremove_wake_function() 就是内核提供的唤醒等待队列中进程的方法,它其实主要做两件事:1. 调用 default_wake_function() 来唤醒进程;2. 把等待队列从等待队列头中删除。

  关于唤醒,内核最主要会调用到 __wake_up_common() 这个函数,下面是它的代码实现:

  static void __wake_up_common(wait_queue_head_t *q, unsigned int mode, int nr_exclusive, int sync, void *key)

  {

  wait_queue_t *curr, *next;

  list_for_each_entry_safe(curr, next, &q->task_list, task_list) {

  unsigned flags = curr->flags;

  if (curr->func(curr, mode, sync, key) && (flags & WQ_FLAG_EXCLUSIVE) && !–nr_exclusive)

  break;

  }

  }

  其他变种

  关于休眠和唤醒,内核还提供了一些其他变种的方法,这里就不一一说明了,下面只列出了一些常用的宏和函数名称。

  wait_event(queue, condition);

  wait_event_interruptible(queue, condition);

  wait_event_timeout(queue, condition, timeout);

  wait_event_interruptible_timeout(queue, condition, timeout);

  void prepare_to_wait(wait_queue_head_t *q, wait_queue_t *wait, int state)

  void prepare_to_wait_exclusive(wait_queue_head_t *q, wait_queue_t *wait, int state)

  wake_up(queue)

  wake_up_nr(queue, nr)

  wake_up_interruptible(queue)

  wake_up_interruptible_nr(queue, nr)

  休眠规则

  不要在原子上下文中休眠。

  禁止中断时,也不能休眠。

  要确保有进程能唤醒自己。

  休眠被唤醒之后仍要检查等待的条件是否为真,否则重新继续休眠。

  转载于纳尼的新浪博客

  许多时间以来,在国产网游不断前进与发展的道路上,总是伴随着谩骂与诟病,甚至放眼到现在,为我们所津津的乐道的只是以《魔兽世界》为代表的西方魔幻网游,而最能够体现中国民族传统文化的武侠网游却少之又少。即便是现在,以《千年》、《热血江湖》等为代表的韩国武侠网游依然在我们心目中占据着重要的位置。然而讽刺性的现实却在不断告诉我们,真正对武侠有着强烈认知度并且有着强烈武侠情结的民族,是不折不扣的中国人。无论是小说、电影亦或者是功夫明星,中华武侠浓烈的韵味都时刻伴随着我们左右。

  而在每一个中国人心中,武侠的梦想也从未泯灭。乱世江湖,盖世神功,侠骨柔情,快意恩仇。我们从小或许都在幻想着有一天可以浪迹江湖,不问红尘俗世吧。然而这些仅仅是武侠世界给人的意境之美,个人认为更加浓烈地武侠氛围则更应该注重对侠义精神、门派归属以及民族大义的表达。

  剧情式带入兴起的武侠网游

  支离破碎的《金庸群侠传OL》,应该可以算是武侠游戏最古老的对于江湖的表达与揣摩,其版本众多,无论是单机亦或是网络版,都有着为数众多的粉丝群。即便是在21世纪初韩游林立的国内市场也依然风采照人、屹立不倒。

  之所以给“网金”以“支离破碎”的修饰,源于“网金”整体游戏世界观的零散。因为其武侠世界观更多的是侧重于金庸小说的故事情节的代入,而展现的并非是庞大并且有着灵性的纯正江湖。但是这并不妨碍我们对于“网金”的深爱,或许也正是由于这最初的试水,才使得国产网游研发商见识到武侠的独特魅力,而武侠网络游戏也正因此才如雨后春笋般地不断涌现出来。

  侠骨柔情与民族大义的交融

  当《传奇》已经在大陆运营地风生水起时,国产网游的自主研发才真正开始发力,这其中便有后来广为国内玩家熟知的网易“西游”题材网游,而与此同时,金山西山居根据单机“剑侠情缘”系列所改编的网络版武侠游戏也赢得了玩家的喝彩。

  并且对于《剑侠情缘》所营造的武侠世界已经开始完全摒弃了对于武侠世界的刻意追求,也不再如“网金”那般纯粹的以故事情节为主体来展现庞大的武侠世界观,相反更多的则是将感情与民族大义融为一体地表达,在这点上,“剑侠”系列也着实给我们带来“侠之大者,为国为民”的深度武侠英雄主义荣誉感。一直到现在《剑网三》,这部助推着金山前进的动力源泉都有着巨大的力量,但发展到“剑三”,由于过度的仿魔兽以及在当下添加诸多一味迎合市场口味而颠覆传统武侠文化的元素,使得“剑侠情缘”已经离真正的武侠世界越来越远。

  同名武侠小说的门派归属感

  继“剑侠情缘”网络版之后,国产武侠网游在很长一段时间里都没能够诞生出一款轰动时人的产品,而2004在中国大地上飘来的韩国网游《热血传奇》便正好巧合性地填补了这一空白,但是由于民族文化与历史沉淀的不同,以及游戏自身Q版的人物设计都完全背离了国人印象中的那种武侠感觉,所以使得其对中国武侠世界没有任何的颠覆性作用。

  时间继续不助的前行,我们终于在2007年又见国产武侠网游。这款由搜狐自主研发的2.5D网游《****》根据金庸同名武侠小说改编,历时三年多运营,目前生命力依然旺盛。个人感觉其对武侠世界的阐述更多的侧重于对门派归属感的表达,这从游戏版本的更新与各门派玩家在论坛中互喷的现象中便可以感受出来。但是无论2.5D视角的局限性,亦或是武侠网游应具备的各类要素都显得对武侠世界的表达仍然不够凸显。

  正本清源意境的纯武侠回归

  由于国产武侠网游长期一味的模仿欧美魔幻风,使得国内研发商在国产网游新十年共同发起呐喊,力求打造出带有浓烈中国风韵味的武侠网游。其中便有以研发闻名的像素旗下的《刀剑·封魔录》、完美时空旗下昱泉出品的《笑傲江湖》、久游旗下自主研发的《流星蝴蝶剑OL》以及国内最早的3D网游研发商蜗牛旗下的《九阴真经》。

  虽然此类产品同为3D类武侠网游,并且之间有着诸多雷同的设计元素,但是我们还是能够深刻地感受出各自的不同。以《九阴真经》为例,无等级无职业、永不下线、摒弃战法牧等概念都给我们表达出不同于以往的武侠世界,而绵延万里的大明山河,繁复细琐的草根社会,爱恨交织的江湖生涯,正邪两立的门派恩怨,刀光剑影的武林争雄,深邃玄妙的内功心法,飞檐走壁的轻功打斗,环环相扣的市井悬案等众多我们在经典武侠小说或影视剧中亲眼所见的桥段更是将武侠世界的微小细节通过游戏表现的更加深刻,“真武侠社区网游”的定位更使得武侠应该具备的人人之间交互的江湖味道十足。

  从最初的“网金”,到当前还未面世的众多3D武侠网游新作,我们毫无不怀疑地相信,具有浓厚中国文化符号代表性的武侠网游产品一直能在带给这我们全新的武侠游戏体验,而究竟国产武侠网游能否塑造成为东方的“魔兽世界”,还有待于市场的校验!

2010-10-21

  在使用 vi 编辑器时 — 无论是初次使用的用户,还是有经验的用户 — 大多数人往往只掌握核心命令集,这些命令可以执行最常用的功能:导航或保存文件;插入、更新、删除或搜索数据;退出但不保存修改。

  但是,vi 编辑器极其强大,特性和功能非常丰富。即使在多年使用 vi 之后,您仍然可能会发现有不知道的新命令。本文讨论的命令就属于不太为人所知的命令,但是它们可以简化您目前采用的操作方法,让您的工作方式更高效,或者让您能够完成原来不知道可以用 vi 完成的操作。

  打开和关闭行号

  vi 编辑器的许多选项可以控制编辑会话的外观和感觉。使用 :set 命令修改 vi 中的会话设置。按 Escape 键进入命令模式之后,可以使用 :set all 命令显示选项和设置的列表。

  可以设置的选项之一是 number,它的作用是打开和关闭行号(见 清单 1)。

  清单 1. 打开行号之前

  #

  # Internet host table

  #

  ::1 localhost

  127.0.0.1 localhost loghost

  192.168.0.6 centos5

  192.168.0.10 appserv

  192.168.0.11 webserv

  192.168.0.12 test

  192.168.0.5 solaris10 # Added by DHCP

  ~

  ~

  ~

  :set number

  这个命令让 vi 在当前编辑的文件中的每个记录上显示行号。让 vi 进入命令模式之后,可以输入 :set number 并按回车来打开行号(见 清单 2)。

  清单 2. 打开行号之后

  1 #

  2 # Internet host table

  3 #

  4 ::1 localhost

  5 127.0.0.1 localhost loghost

  6 192.168.0.6 centos5

  7 192.168.0.10 appserv

  8 192.168.0.11 webserv

  9 192.168.0.12 test

  10 192.168.0.5 solaris10 # Added by DHCP

  ~

  ~

  ~

  :set number

  可以使用 :set nonumber 命令关闭行号。还可以使用这个命令和 :set number 命令的简写,即 :set nu 和 :set nonu。

  如果需要快速计算要用 vi 函数处理的行数,显示行号会非常有帮助。当行数很多,可能跨多个屏幕时,行号尤其有用。另外,有时候您知道要处理的行范围,但是需要查明要在 vi 命令中使用的初始和结束行号。

  如果希望每次进入 vi 会话时都显示行号,那么在主目录中的 .exrc 文件中添加 set number 行。

  自动缩进

  在用某些编程语言编写代码时,缩进是样式的重要部分,可以确保代码的可读性更好。如果需要,可以在 vi 编辑器中根据编程语言的样式设置自动缩进。使用 autoindent 打开或关闭自动缩进(见 清单 3)。

  清单 3. 打开自动缩进

  #!/bin/ksh

  #

  #

  for file in /etc/*

  do

  if [[ -f ${file} ]] ; then

  echo “${file} is a file”

  ~

  ~

  ~

  ~

  ~

  :set autoindent

  在此之后,如果在一行的开头输入空格或制表符,那么后续的新行将会缩进到相同的位置。在命令模式下,输入 :set autoindent,然后按回车打开自动缩进。通过设置 shiftwidth 确定缩进级别。例如,:set shiftwidth=4 把每级缩进设置为四个空格(见 清单 4)。

  清单 4. 设置缩进级别

  #!/bin/ksh

  #

  #

  for file in /etc/*

  do

  if [[ -f ${file} ]] ; then

  echo “${file} is a file”

  elif [[ -d ${file} ]] ; then

  echo “${file} is a directory”

  fi

  done

  ~

  ~

  :set shiftwidth=4

  在命令模式下,可以使用 >> 命令让现有的一行增加一级缩进,使用 << 命令减少一级缩进。在这些命令前面加上一个整数,即可让多行增加或减少一级缩进。例如,把游标放在 清单 4 中第 6 行的开头,进入命令模式之后,输入 5>> 就会让下面五行增加一级缩进。清单 5 显示结果。

  清单 5. 缩进代码块

  #!/bin/ksh

  #

  #

  for file in /etc/*

  do

  if [[ -f ${file} ]] ; then

  echo “${file} is a file”

  elif [[ -d ${file} ]] ; then

  echo “${file} is a directory”

  fi

  done

  ~

  ~

  可以使用 :set noautoindent 命令关闭自动缩进。还可以使用这个命令和 autoindent 命令的简写,即 :set ai 和 :set noai。还可以使用 :set ai sw=4 在一个命令中打开缩进并设置缩进级别。

  如果希望每次启动 vi 会话时都启用自动缩进并把缩进级别设置为四个空格,那么在主目录中的 .exrc 文件中添加 set ai sw=4 行。

  在搜索时不区分大小写

  如您所知,在 UNIX® 中执行搜索时,模式匹配是区分大小写的。但是,如果希望 vi 不区分大小写,那么可以使用 :set ignorecase 命令。使用 :set noignorecase 恢复区分大小写。还可以使用简写(:set ic 和 :set noic)。

  如果希望每次进入 vi 会话时都启用不区分大小写的搜索,那么在主目录中的 .exrc 文件中添加 set ignorecase 行。

  复合搜索

  在 vi 中,可以使用 / 命令搜索字符串,这需要以字面字符串或正则表达式的形式指定要匹配的模式。例如,要想在文件中搜索单词 echo,只需进入命令模式,输入 /echo,然后按回车。这个命令会找到 清单 6 所示文件的第 3 行的第一个单词。

  清单 6. 复合搜索

  1 #!/bin/ksh

  2 #

  3 echo “Starting”

  4 file=${1}

  5

  6 echo ${file}

  7

  8 if [[ ${file} = 1 ]] ; then

  9 ((file=${file}+1))

  10 echo “Adding one gives ” \

  11 ${file}

  12 fi

  13 echo “Ending”

  14 exit

  ~

  ~

  可以使用简单的正则表达式指定寻找包含某一单词而且后面有另一个单词的行。例如,要想寻找包含字符串 echo、后面有零个或更多字符、之后是字符串 file 的第一行,应该使用 /echo.*file。在 清单 6 所示的文件中,这个命令会找到第 6 行的第一个单词。

  但是,只有这两个字符串出现在同一行上,这个命令才认为是匹配的。如果希望搜索出现在另一个模式或字符串后面的某个模式或字符串,不管这两个模式或字符串是否在同一行上,那么可以指定由分号 (;) 分隔的两个搜索命令,从而执行复合搜索。例如,要想搜索出现在字符串 {file}+1 后面的字符串 echo,应该使用 /{file}+1/;/echo/。在 清单 6 所示的文件中,这个命令会找到第 10 行的第一个单词。

  复合搜索对于寻找代码中出现在另一个命令后面的某个命令尤其有用 — 例如,在设置某个变量之后调用函数的地方。

  重放搜索模式

  当在文件中搜索要替换的模式时,可以让 vi 把要匹配的任何模式保存在缓冲区中;然后,在执行替换时,可以用缓冲区引用号重放它们。方法是把模式放在 \( 和 \) 之间,这会指示 vi 把模式放在编号的缓冲区(1 到 9)中。在执行替换时,可以用缓冲区引用号 \1 到 \9 引用这些缓冲区。

  例如,假设要在 清单 7 所示的文件中搜索以单词 Martin 开头的行并对每个匹配添加前缀 Mr 和后缀 Wicks,那么进入命令模式,输入 vi 命令 :%s/^\(Martin\)/Mr \1 Wicks/g,然后按回车。

  清单 7. 重放搜索模式(之前)

  Martin is an IT consultant. Martin likes

  snowboarding and mountain biking. Martin has

  worked on UNIX systems for over 15 years. Martin also

  worked for many years before that on mainframes.

  Martin lives in London.

  ~

  ~

  ~

  ~

  :%s/^\(Martin\)/Mr \1 Wicks/g

  下面把这个命令分解开解释一下:

  :%s — 指示 vi 执行替换。

  / — 模式分隔符。

  ^\(Martin\) — 寻找以字符串 Martin 开头的行并把这个字符串保存在缓冲区 1 中。

  / — 模式分隔符。

  Mr \1 Wicks — 把找到的字符串替换为字符串 Mr,加上缓冲区 1 中的内容,再加上字符串 Wicks。

  / — 模式分隔符。

  g — 全局修改(即修改所有匹配的地方)。

  在搜索和替换字符串中都可以使用缓冲区引用。

  红楼梦再次被翻拍,西游记N个版本的出现,无疑不体现出名作经典的魅力,大家的靠名作拉钱进兜里啊,撒东西套上CCAV套上四大名作,要赚钱总跑不了谱。

  虽说有着庞大的粉丝群以及一群义无反顾,盲目崇尚经典之作的翻拍者门的存在,但是众多的经典又是如何被演绎进网游,网游纵然也是翻拍大军中的一小股游击,从四大名著到单机再到网络小说无一遗漏。

  大话西游系列

  两代经典一再延续,与电影同名,全版本多达11个资料片,堪称网游更新史的一代传奇。根据同名电影改编,电影的蓝本也是西游记所改而成。

  梦幻西游

  史上最赚钱的游戏之一,网易除了魔兽外的招牌之作,看到代言人请的周董就晓得啦,梦幻西游就是系游戏的幻想版,内容可爱多趣,当年可是吸引了多少多少人的眼光。话说周董这次代言怎么没cos个什么角色的,例如猪八戒,例如沙僧,太不给力了。

  红楼Q梦

  虽然这个是拿来凑数的,但怎么也要凑齐4大名著吧,红楼Q梦按照红楼梦的故事背景改编,好吧你们都是改编的,改编,就是用了点故事情节用了点名字当NPC的代号,好吧。。改编。。编。。。

  大话水浒

  火石开发的回合制游戏,之前的水浒Q传可谓是风靡了国产回合制游戏爱好者之间。重新推出大话水浒,有着何等意义?算是水浒Q传的借尸还魂之作?

  三国志

  三国系列的产品太多太多了,就拿KOEI家的三国志OL来说吧,从单机到PS 到PS2 再到PSP,几乎每一代家用机都可以但到它的身影,按照三国志内容改变的动作游戏,可以说几乎是按着当时的内容所改变的,从角色设定到武器到人物相关关系,不得不称赞日本人做的游戏细节看着真爽,爽死了啊~~

  金庸群侠传

  可以说是寿命非常长久的一款游戏,倒是中华网龙的台湾公司开发的,在台湾依旧火爆,看台湾偶像剧的时候经常可以看到广告,台湾对于网游广告的限制度不高,可以看到很恶俗的广告-。-有兴趣的可以去蛋疼偶像剧直播版看看。

  回到正题,金庸群侠传,固然是金庸小说改变的游戏,当时的小说fans几乎成了第一批网游玩家,可谓是目前靠原作吸引力最强大的一款游戏。

  诛仙

  原本这里想写仙剑奇侠传,可惜写到现在全都是小说改变,于是忽略之~~

  诛仙的小说占据盛大起点文学的N周排行榜头牌之位,可见吸引力之强悍,在完美时空购买其版权后,直接改为游戏,3DMMO成为了当年的主流游戏,美貌的人群,将小说中幻想的一树一草一木还原出来,将堵着心目中各种角色还原成3D人型,无疑在玩游戏的同时,让小说fans回想起小说中的某一个情节。

  梦幻诛仙

  此后,小说再次改编成Q版回合制,配合游戏内的御剑飞行,再次成为2D网游中的神话,2D游戏依旧能飞行!!!如今梦幻诛仙周年庆之际,各位是否还记得完美时空当年主打的banner的solgin??依稀记得“2D游戏能飞行,首款飞行2D网游”的主题那。

  鬼吹灯

  这里不得不提起他啊,当年麦石做这款游戏的时候,鬼吹灯红的都快发黑了,过了几年后,游趣再来添了一把柴,于是这个小说跟着游戏又火了一把。话说游趣的人设漂亮(¯﹃¯)而当时又碰巧是鬼吹灯2再次驾临,于是两大鬼吹灯再次PK,是为小说造势?还是小说为游戏造势?话说盛大那个鬼吹灯为了避免冲突改成鬼吹灯外传ol了?

2010-10-20

 (转自沈闻涧的博客)

  从国美电器内乱发生至今的2个多月内,作为在长达10年时间内一直保持着“针锋相对”竞争关系的苏宁电器,并未对国美事件发表过任何意见和看法。不过,却加快了开店的步伐和海外扩张的进程。虽然苏宁方面极力否认,这与国美内乱有关联,但明眼人大可想像,这其中必然存在着“敌退我进”的拉锯式竞争关系。

  就中国人的传统而言,连“清官难断家务事”,更何况作为一家长期虎视眈眈国美占据的那个中国家电连锁业霸主宝座的对手,保持沉默成为苏宁电器最好的应对举措。但在近10年竞争中一直处在跟随地位的苏宁电器,一朝获得了因竞争对手内乱而“免费馈赠”的大好发展良机,未免会有些“喜形于色”。

  在黄金周之后的家电零售业绩盘点中,就出现了“北京苏宁已经超越北京国美”的论调,而北京苏宁的掌舵人范志军,其另一身份则是苏宁电器的副总裁。因此,其它地区的苏宁电器分部难免不会跟进这一“超越”论调。最终,这也正好验证了黄光裕家族对于“陈晓领军下的国美电器后劲不足”的论调。

  一般意义上说,作为中国家电连锁业态的两大巨头,苏宁并不愿意对手国美因内乱而就此沦落或者下滑。毕竟,一旦国内家电连锁业只有苏宁一只“领头羊”,无疑会“树大招风”从而为企业的发展引来更多的阻力和对手。

  眼下,国美的阶段性内乱已经给苏宁的发展和超越提供了“千载良机”。如果国美这场内乱长期持续而得不到根治和解决,这必将引发国内家电连锁业态的新一轮洗牌和变革,从而造就几家新的全国性家电连锁商,同时还会从根本上确立苏宁在家电连锁业的“一家独大”领军地位。

  显然,对于苏宁电器未来发展而言,一家独大虽然短期内暗藏诸多无形的风险和无法说清的压力,但没有企业愿意只屈居“亚军”而成为冠军的陪衬。成为行业的领导者,这是苏宁电器创始人张近东这样的新时代中国企业家毕身所追求和奋斗的目标。或许,在张近东看来,超越国美只是阶段性的目标,打造全球性的家电连锁巨头才是企业追求的最终目标。因此,无论是国美的短期性内部,或者是未来可能会长期性控制权争夺,对于苏宁而言,超越并逐步扩大领先地位的目标是明确的,而扩张与发展的道路也是清晰的。

  虽然当前国美内乱还未影响到其众多终端门店的销售。如果,这场内乱在今年底之前得不到根本性的解决,而一旦2011年度中国家电市场竞争大幕的徐徐拉开,这必然会引发众多中外家电企业对于国美电器新年度发展和走势的担忧。从而将原本“国美、苏宁”对等的天平出现向苏宁的单边性倾斜。这虽然是所有国美电器经营层所不愿意看到的,但现实往往是非常残酷,众多中外家电企业也非常务实,特别是面对每年高达10亿——1000亿元不等的合作规模,帮助的心理只是暂时的,而持续双赢才是维持合作的纽带。

  当“家丑已经外扬”,国美方面则必须要尽快根治,否则苏宁的无声音抢夺将会更加疯狂,最终还会让国美电器不仅丢尽脸面,还将输掉市场。

  我们在平时的电脑操作过程中,有时会碰到想要删除某个文件时,系统却提示无法删除(如图1),在切换到DOS状态下或者是在安全模式中虽然可以删除,但是这样操作起来却有点麻烦。

 

  我们不妨想一想,用一个简单的办法来解决这个问题:首先用鼠标右键单击“回收站”图标,从快捷菜单中选择“属性”命令,打开“回收站属性”对话框,选择“全局”选项卡,把“回收站的最大空间”设为0%,设置(如图2)所示。确定后,再试试删除刚才删不了的文件,一般就可以了。

  关闭 XP 内设的烧碟功能:

  如果不打算使用此功能可将其关闭,可加快使用 Nero 烧录软件的速度,因为Windows XP 的烧录系统由 Roxio 公司提供 (即与 Easy Cd Creator 同公司)。

  在〔控制面板〕〔管理工具〕〔服务〕在右边窗口选〔IMAPI CD-Burning COM Service〕〔启动类型〕选〔已停用〕

  关机时自动关闭停止响应程序:

  在〔开始〕〔运行〕键入〔Regedit〕〔HKEY_USERS〕〔.DEFAULT〕〔Control Panel〕在〔Desktop〕右面窗口将〔AutoEndTasks〕的数值资料改为〔1〕

  注销或重新启动即可。

  移除Windows Messenger:

  先用 Wordpad 打开 X:WINDOWSinf 下的 sysoc.inf 档案

  X=(XP所在的磁盘区)

  将内容〔msmsgs=msgrocm.dll,OcEntry,msmsgs.inf,hide,7〕

  更改为〔msmsgs=msgrocm.dll,OcEntry,msmsgs.inf,7〕

  存档及退出

  然后在〔控制面板〕〔添加或删除程序〕〔添加/删除 Windows 组件〕不选〔Windows Messenger〕〔下一步〕〔完成〕后便成功移除。

  停止“磁盘空间不足”的通知 :

  当磁盘驱动器的容量少于 200MB 时 Windows XP 便会发出“磁盘空间不足”的通知

  如需停止此功能,可按下面程序更改登录文件

  在〔开始〕〔运行〕键入〔Regedit〕〔HKEY_LOCAL_MACHINE〕〔Software〕〔Microsoft〕〔Windows〕〔CurrentVersion〕在〔Policies〕下增加一个机码名〔Explorer〕(如果已有便不用增加)在〔Explorer〕增加一个 DWORD 值〔NoLowDiskSpaceChecks〕

  数值数据为〔1〕= 停止通知,值数据为〔0〕= 默认值启动通知

  关闭 windows 自动更新 :

  鼠标右点〔我的电脑〕〔内容〕〔自动更新〕

  选“关闭自动更新,我要手动更新我的计算机”

  关闭启动时窗口标志画面:

  在〔开始〕〔运行〕键入〔msconfig〕选〔boot.ini〕

  然后在〔启动选项〕内选〔NOGUIBOOT]

  重新开机便没有了窗口标志的画面

  使用 Windows Media Player 9 播放 DVD 盘:

  在〔开始〕〔运行〕键入〔DVDPlay〕便会出现 Windows Media Player

  按播放 VCD 型式操作便可播放 DVD 了,当然你一定要有 DVDRom 装置

  如果还出现问题,在〔开始〕〔运行〕键入〔regedit〕选〔HKEY_CURRENT_USER〕

  〔Software〕〔Microsoft〕〔MediaPlayer〕〔Player〕在〔Settings〕右边窗口

  增加一个字符串值〔EnableDVDUI〕数值数据为〔yes〕

  关闭自动重新启动功能:

  当 Windows XP 遇到严重问题时便会突然重新开机,按下更改可以取消此功能

  在〔开始〕〔运行〕键入〔regedit〕选〔HKEY_LOCAL_MACHINE〕〔SYSTEM〕

  〔CurrentControlSet〕〔Control〕〔CrashControl〕将〔AutoReboot〕dword 值更改为〔0〕重新开机生效

  移除共享文档:

  除正常〔我的文档〕及〔共享文档夹〕外,每个用户都会有一个独立的活页夹,

  如下设定则只会保留我的活页夹,其余的不会显示出来

  在〔开始〕〔运行〕键入〔regedit〕选〔HKEY_LOCAL_MACHINE〕〔SOFTWARE〕

  〔Microsoft〕〔Windows〕〔CurrentVersion〕〔Explorer〕〔MyComputer〕〔NameSpace〕在〔DelegateFolders〕下删除〔{59031a47-3f72-44a7-89c5-5595fe6b30ee}〕机码

  取消 IE 自动缩图功能:

  Internet Explorer 6 在浏览图片如大出屏幕,图片便会自动缩小如需取消这功能可按如下修改:

  在〔开始〕〔运行〕键入〔regedit〕〔HKEY_CURRENT_USER〕〔Software〕〔Microsoft〕〔Internet Explorer〕在〔Main〕增加一个字符串值〔Enable AutoImageResize〕数据数值为〔NO〕

  让 IE6 可以同时下载超过两个档案:

  Internet Explorer 6 同时最多只可以下载两个档案,

  按下修改可同时下载多达十个档案

  在〔开始〕〔运行〕键入〔regedit〕〔HKEY_CURRENT_USER〕〔Software〕〔Microsoft〕〔Windows〕〔CurrentVersion〕〔InternetSettings〕

  在右边窗口增加下列两个〔Dword〕值

  〔MaxConnectionsPer1_0Server〕数值资料为〔0000000a〕即十进制〔10〕

  〔MaxConnectionsPerServer〕数值资料为〔0000000a〕即十进制〔10〕

  重新启动计算机生效 加快宽频连接速度:

  在〔开始〕〔运行〕键入〔regedit〕在〔HKEY_LOCAL_MACHINE〕〔SOFTWARE〕〔Policies〕〔Microsoft〕 〔Windows〕

  增加一个名为〔Psched〕的机码

  在〔Psched〕右面窗口增加一个 Dword 值〔NonBestEffortLimit〕数值数据为〔0〕

  『仅适用用 Windows XP 家用版本』

  加快菜单显示速度:

  在〔开始〕〔运行〕键入〔Regedit〕〔HKEY_CURRENT_USER〕〔Control Panel〕〔Desktop〕将字符串值〔MenuShowDelay〕的数值数据更改为〔0〕

  调整后如觉得菜单显示速度太快而不适应者可将〔MenuShowDelay〕的数值数据更改为〔200〕

  重新启动生效 。

  加快自动更新率:

  在〔开始〕〔运行〕键入〔Regedit〕〔HKEY_LOCAL_MACHINE〕〔System〕〔CurrentControlSet〕〔Control〕〔Update〕将 Dword〔UpdateMode〕的数值数据更改为〔0〕。重新启动生效。

  关闭启动时加载不需要的程序:

  如开机时有太多的程序要运行会影响开机的速度,先检查哪些些档案会在开机时运行

  在〔开始〕〔运行〕键入〔msconfig〕选〔启动〕

  在启动内的程序是代表开机时要运行的程序,如需暂时停止运行某些程序便取消在〔□〕的〔X〕符号便可,如想恢复开机时运行此程序在〔□〕内加回〔X〕符号便可。

  停用不需要的服务:

  在〔开始〕〔运行〕键入〔services.msc〕打开服务窗口

  检查右边窗口将不需要的服务在〔启动类型〕内选〔已禁止〕;再在〔服务状态〕中选〔停用〕

  善用 CPU 的 L2 Cache 加快整体效能:

  在〔开始〕〔运行〕键入〔Regedit〕〔HKEY_LOCAL_MACHINE〕〔SYSTEM〕〔CurrentControlSet〕〔Control〕〔SessionManager〕在〔MemoryManagement〕的右边窗口将〔SecondLevelDataCache〕的数值数据更改为与 CPU L2 Cache 相同的十进制数值

  例:P4 1.6G 的 L2 Cache 为 256Kb,数值数据更改为十进制数值 256

  有关 L2 Cache 的数值并非如某些不负责任的网页乱抄过来,例如 P4 1.6G 的 L2 Cache 为 256Kb,但 P4 1.6GA 的 L2 Cache 为 512Kb

  读者可以通过网络查询到有关 CPU 的 L2 Cache 的资料。

  在启动计算机时运行 Defrag 程序 :

  在〔开始〕〔运行〕键入〔Regedit〕〔HKEY_LOCAL_MACHINE〕〔SOFTWARE〕〔Microsoft〕〔Dfrg〕〔BootOptimizeFunction 〕

  将字符串值〔Enable〕设定为〔Y〕等于开启,而设定为〔N〕等于关闭。

  减少多重启动时等待时间:

  方法一:用 Notepad 打开在 C: 目录下的 boot.ini 档案,将内容〔timeout〕的设定值由预设的 30 (秒) 改为要求等待的秒数数字,存盘。

  方法二:也可以通过〔开始〕〔运行〕键入〔msconfig〕,打开boot.ini 选项,进行秒数的修改。

  方法三:右键点击“我的电脑”,选择属性高级启动和故障恢复设置,在此修改启动等待时间。

  加快开机与关机的速度:

  ①选“开始运行”,键入Regedit,展开HKEY_CURRENT_USERControl PanelDesktop,将字符串值“HungAppTimeout”的数值更改为200,再将字符串值“WaitToKillAppTimeout”的数值数据更改为1000;

  ②另在HKEY_LOCAL_MACHINESystemCurrentControlSetControl下,将字符串值“HungAppTimeout”的数值数据更改为200,将字符串值“WaitToKillServiceTimeout”的数值数据更改为〔1000〕;

  ③使用微软 Bootvis.exe 优化启动速度。我们到微软官方网站先下载 bootVis.exe,然后解压后运行bootvis.exe,之后在Trace下选next boot和driver delays等,此后XP会重新启动,并将记录启动数据产生成BIN的文件。再在“fileopen中打开这个文件,在Trace下选Optimize system即可。

  提示:此优化需时颇长,请耐心等待。

  清除注册表内不用的DLL文件:

  在〔开始〕〔运行〕键入〔Regedit〕〔HKKEY_LOCAL_MACHINE〕〔SOFTWARE〕〔Microsoft〕〔Windows〕〔CurrentVersion〕〔Explorer〕

  增加一个机码〔AlwaysUnloadDLL〕默认值为〔1〕

  如默认值设定为〔0〕则代表停用此功能

  加快宽频连接速度:

  在〔开始〕〔运行〕键入〔regedit〕在〔HKEY_LOCAL_MACHINE〕〔SOFTWARE〕〔Policies〕〔Microsoft〕 〔Windows〕

  增加一个名为〔Psched〕的机码

  在〔Psched〕右面窗口增加一个 Dword 值〔NonBestEffortLimit〕数值数据为〔0〕

  『仅适用用 Windows XP 家用版本』

  加快菜单显示速度:

  在〔开始〕〔运行〕键入〔Regedit〕〔HKEY_CURRENT_USER〕〔Control Panel〕〔Desktop〕将字符串值〔MenuShowDelay〕的数值数据更改为〔0〕

  调整后如觉得菜单显示速度太快而不适应者可将〔MenuShowDelay〕的数值数据更改为〔200〕

  重新启动生效 。

  加快自动更新率:

  在〔开始〕〔运行〕键入〔Regedit〕〔HKEY_LOCAL_MACHINE〕〔System〕〔CurrentControlSet〕〔Control〕〔Update〕将 Dword〔Updateode〕的数值数据更改为〔0〕。重新启动生效。

  关闭启动时加载不需要的程序:

  如开机时有太多的程序要运行会影响开机的速度,先检查哪些些档案会在开机时运行

  在〔开始〕〔运行〕键入〔msconfig〕选〔启动〕

  在启动内的程序是代表开机时要运行的程序,如需暂时停止运行某些程序便取消在〔□〕的〔X〕符号便可,如想恢复开机时运行此程序在〔□〕内加回〔X〕符号便可。

  停用不需要的服务:

  在〔开始〕〔运行〕键入〔services.msc〕打开服务窗口

  检查右边窗口将不需要的服务在〔启动类型〕内选〔已禁止〕;再在〔服务状态〕中选〔停用〕

  善用 CPU 的 L2 Cache 加快整体效能:

  在〔开始〕〔运行〕键入〔Regedit〕〔HKEY_LOCAL_MACHINE〕〔SYSTEM〕〔CurrentControlSet〕〔Control〕〔SessionManager〕在〔MemoryManagement〕的右边窗口将〔SecondLevelDataCache〕的数值数据更改为与 CPU L2 Cache 相同的十进制数值

  例:P4 1.6G 的 L2 Cache 为 256Kb,数值数据更改为十进制数值 256

  有关 L2 Cache 的数值并非如某些不负责任的网页乱抄过来,例如 P4 1.6G 的 L2 Cache 为 256Kb,但 P4 1.6GA 的 L2 Cache 为 512Kb

  读者可以通过网络查询到有关 CPU 的 L2 Cache 的资料。

  typedef用来声明一个别名,typedef后面的语法,是一个声明。本来笔者以为这里不会产生什么误解的,但结果却出乎意料,产生误解的人不在少数。罪魁祸首又是那些害人的教材。在这些教材中介绍typedef的时候通常会写出如下形式: typedef int PARA; 这种形式跟#define int PARA几乎一样,如前面几章所述,这些教材的宗旨是由浅入深,但实际做出来的行为却是以偏盖全。的确,这种形式在所有形式中是最简单的,但却没有对 typedef进一步解释,使得不少人用#define的思维来看待typedef,把int与PARA分开来看,int是一部分,PARA是另一部分,但实际上根本就不是这么一回事。int与PARA是一个整体!就象int i:声明一样是一个整体声明,只不过int i定义了一个变量,而typedef定义了一个别名。

  这些人由于持有这种错误的观念,就会无法理解如下一些声明:typedef int a[10]; typedef void (*p)(void); 他们会以为a[10]是int的别名,(*p)(void)是void的别名,但这样的别名看起来又似乎不是合法的名字,于是陷入困惑之中。实际上,上面的语句把a声明为具有10个int元素的数组的类型别名,p是一种函数指针的类型别名。 虽然在功能上,typedef可以看作一个跟int PARA分离的动作,但语法上typedef属于存储类声明说明符,因此严格来说,typedef int PARA整个是一个完整的声明。 定义一个函数指针类型。 比如原函数是 void func(void); 那么定义的函数指针类型就是typedef void (*Fun)(void); 然后用此类型生成一个指向函数的指针: Fun func1; 当func1获取函数地址之后,那么你就可以向调用原函数那样来使用这个函数指针: func1(void);

  一、用途和陷阱

  用途一:

  定义一种类型的别名,而不只是简单的宏替换。可以用作同时声明指针型的多个对象。比如:

  char* pa, pb; // 这多数不符合我们的意图,它只声明了一个指向字符变量的指针,

  // 和一个字符变量;

  以下则可行:

  typedef char* PCHAR; // 一般用大写

  PCHAR pa, pb; // 可行,同时声明了两个指向字符变量的指针

  虽然:

  char *pa, *pb;

  也可行,但相对来说没有用typedef的形式直观,尤其在需要大量指针的地方,typedef的方式更省事。

  用途二:

  用在旧的C代码中(具体多旧没有查),帮助struct。以前的代码中,声明struct新对象时,必须要带上struct,即形式为: struct 结构名 对象名,如:

  struct tagPOINT1

  {

  int x;

  int y;

  };

  struct tagPOINT1 p1;

  而在C++中,则可以直接写:结构名 对象名,即:

  tagPOINT1 p1;

  估计某人觉得经常多写一个struct太麻烦了,于是就发明了:

  typedef struct tagPOINT

  {

  int x;

  int y;

  }POINT;

  POINT p1; // 这样就比原来的方式少写了一个struct,比较省事,尤其在大量使用的时候

  或许,在C++中,typedef的这种用途二不是很大,但是理解了它,对掌握以前的旧代码还是有帮助的,毕竟我们在项目中有可能会遇到较早些年代遗留下来的代码。

  用途三:

  用typedef来定义与平台无关的类型。

  比如定义一个叫 REAL 的浮点类型,在目标平台一上,让它表示最高精度的类型为:

  typedef long double REAL;

  在不支持 long double 的平台二上,改为:

  typedef double REAL;

  在连 double 都不支持的平台三上,改为:

  typedef float REAL;

  也就是说,当跨平台时,只要改下 typedef 本身就行,不用对其他源码做任何修改。

  标准库就广泛使用了这个技巧,比如size_t。

  另外,因为typedef是定义了一种类型的新别名,不是简单的字符串替换,所以它比宏来得稳健(虽然用宏有时也可以完成以上的用途)。

  用途四:

  为复杂的声明定义一个新的简单的别名。方法是:在原来的声明里逐步用别名替换一部分复杂声明,如此循环,把带变量名的部分留到最后替换,得到的就是原声明的最简化版。举例:

  1. 原声明:int *(*a[5])(int, char*);

  变量名为a,直接用一个新别名pFun替换a就可以了:

  typedef int *(*pFun)(int, char*);

  原声明的最简化版:

  pFun a[5];

  2. 原声明:void (*b[10]) (void (*)());

  变量名为b,先替换右边部分括号里的,pFunParam为别名一:

  typedef void (*pFunParam)();

  再替换左边的变量b,pFunx为别名二:

  typedef void (*pFunx)(pFunParam);

  原声明的最简化版:

  pFunx b[10];

  3. 原声明:doube(*)() (*e)[9];

  变量名为e,先替换左边部分,pFuny为别名一:

  typedef double(*pFuny)();

  再替换右边的变量e,pFunParamy为别名二

  typedef pFuny (*pFunParamy)[9];

  原声明的最简化版:

  pFunParamy e;

  理解复杂声明可用的“右左法则”:从变量名看起,先往右,再往左,碰到一个圆括号就调转阅读的方向;括号内分析完就跳出括号,还是按先右后左的顺序,如此循环,直到整个声明分析完。举例:

  int (*func)(int *p);

  首先找到变量名func,外面有一对圆括号,而且左边是一个*号,这说明func是一个指针;然后跳出这个圆括号,先看右边,又遇到圆括号,这说明(*func)是一个函数,所以func是一个指向这类函数的指针,即函数指针,这类函数具有int*类型的形参,返回值类型是int。

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

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

  也可以记住2个模式:

  type (*)(….)函数指针

  type (*)[]数组指针

  ———————————

  陷阱一:

  记住,typedef是定义了一种类型的新别名,不同于宏,它不是简单的字符串替换。比如:

  先定义:

  typedef char* PSTR;

  然后:

  int mystrcmp(const PSTR, const PSTR);

  const PSTR实际上相当于const char*吗?不是的,它实际上相当于char* const。

  原因在于const给予了整个指针本身以常量性,也就是形成了常量指针char* const。

  简单来说,记住当const和typedef一起出现时,typedef不会是简单的字符串替换就行。

  陷阱二:

  typedef在语法上是一个存储类的关键字(如auto、extern、mutable、static、register等一样),虽然它并不真正影响对象的存储特性,如:

  typedef static int INT2; //不可行

  编译将失败,会提示“指定了一个以上的存储类”。

  二、typedef和#define的用法与区别

  1、typedef的用法

  在C/C++语言中,typedef常用来定义一个标识符及关键字的别名,它是语言编译过程的一部分,但它并不实际分配内存空间,实例像:

  typedef int INT;

  typedef int ARRAY[10];

  typedef (int*) pINT;

  typedef可以增强程序的可读性,以及标识符的灵活性,但它也有“非直观性”等缺点。

  2、#define的用法

  #define为一宏定义语句,通常用它来定义常量(包括无参量与带参量),以及用来实现那些“表面似和善、背后一长串”的宏,它本身并不在编译过程中进行,而是在这之前(预处理过程)就已经完成了,但也因此难以发现潜在的错误及其它代码维护问题,它的实例像:

  #define INT int

  #define TRUE 1

  #define Add(a,b) ((a)+(b));

  #define Loop_10 for (int i=0; i<10; i++)

  在Scott Meyer的Effective C++一书的条款1中有关于#define语句弊端的分析,以及好的替代方法,大家可参看。

  3、typedef与#define的区别

  从以上的概念便也能基本清楚,typedef只是为了增加可读性而为标识符另起的新名称(仅仅只是个别名),而#define原本在C中是为了定义常量,到了C++,const、enum、inline的出现使它也渐渐成为了起别名的工具。有时很容易搞不清楚与typedef两者到底该用哪个好,如#define INT int这样的语句,用typedef一样可以完成,用哪个好呢?我主张用typedef,因为在早期的许多C编译器中这条语句是非法的,只是现今的编译器又做了扩充。为了尽可能地兼容,一般都遵循#define定义“可读”的常量以及一些宏语句的任务,而typedef则常用来定义关键字、冗长的类型的别名。

  宏定义只是简单的字符串代换(原地扩展),而typedef则不是原地扩展,它的新名字具有一定的封装性,以致于新命名的标识符具有更易定义变量的功能。请看上面第一大点代码的第三行:

  typedef (int*) pINT;

  以及下面这行:

  #define pINT2 int*

  效果相同?实则不同!实践中见差别:pINT a,b;的效果同int *a; int *b;表示定义了两个整型指针变量。而pINT2 a,b;的效果同int *a, b;表示定义了一个整型指针变量a和整型变量b。