﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-yg2362</title><link>http://www.cppblog.com/yg2362/</link><description /><language>zh-cn</language><lastBuildDate>Thu, 23 Apr 2026 10:12:03 GMT</lastBuildDate><pubDate>Thu, 23 Apr 2026 10:12:03 GMT</pubDate><ttl>60</ttl><item><title>大区中分配玩家唯一ID的办法(续)</title><link>http://www.cppblog.com/yg2362/archive/2012/12/06/196061.html</link><dc:creator>梨树阳光</dc:creator><author>梨树阳光</author><pubDate>Thu, 06 Dec 2012 15:01:00 GMT</pubDate><guid>http://www.cppblog.com/yg2362/archive/2012/12/06/196061.html</guid><wfw:comment>http://www.cppblog.com/yg2362/comments/196061.html</wfw:comment><comments>http://www.cppblog.com/yg2362/archive/2012/12/06/196061.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cppblog.com/yg2362/comments/commentRss/196061.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/yg2362/services/trackbacks/196061.html</trackback:ping><description><![CDATA[<span style="font-family: Verdana; font-size: 10pt; ">&nbsp; &nbsp; &nbsp; 之前因为时间匆忙，大区里产生唯一ID只是简单写了一个方法，今天趁着有时间，把里面一些过程写出来，也算是个总结。</span><br /><span style="font-family: Verdana; font-size: 10pt; ">&nbsp; &nbsp; &nbsp; 首先说说需求，现在游戏里数据库为了分散热点，都采用分表方式，以前那种一张表AUTO_INCREMENT的方式显然不行了，那么将唯一ID放到业务进程里可行吗？这个也不好，因为现在后台都是多个部署，每个进程可以保证ID唯一，但是存到数据库的时候就可能重复，所以我们还是得在DB上做文章。</span><br /><span style="font-family: Verdana; font-size: 10pt; ">&nbsp; &nbsp; &nbsp; 因此就有了上篇文章的解决方案，单独一张表，</span><span style="line-height: 19px; font-family: Verdana; font-size: 10pt; ">这张表的作用就是专门产生唯一ID，而且为多个业务提供唯一ID，多进程情况下也不需要锁表，效率比较高，是不是很像设计模式里的工厂。接着我来分析下这张表。我们再来看看表结构和用法<br /></span><span style="background-color: #ffffff; font-family: Verdana; font-size: 13px; line-height: 19px; ">create table SeqTab&nbsp;</span><span style="background-color: #ffffff; font-family: Verdana; font-size: 13px; line-height: 19px; ">(&nbsp;<br /></span>&nbsp; &nbsp;<span style="background-color: #ffffff; font-family: Verdana; font-size: 13px; line-height: 19px; ">iSeqNo bigint(20) not null default 0,</span><span style="font-family: Verdana; ">&nbsp; &nbsp;//表示唯一ID</span><span style="background-color: #ffffff; font-family: Verdana, Arial; font-size: 13px; line-height: 19px; "><br /></span><span style="background-color: #ffffff; font-family: Verdana; font-size: 13px; line-height: 19px; ">&nbsp; &nbsp;iSeqType int(11) not null default 0,</span><span style="font-family: Verdana; ">&nbsp; &nbsp;//表示业务ID</span><span style="background-color: #ffffff; font-family: Verdana, Arial; font-size: 13px; line-height: 19px; "><br /></span><span style="font-family: Verdana; ">&nbsp; &nbsp;primary key(iSeqNo,iSeqType)</span><span style="background-color: #ffffff; font-family: Verdana; font-size: 13px; line-height: 19px; ">);<br /></span>&nbsp; &nbsp;<span style="font-family: Verdana; font-size: 13px; line-height: 19px; background-color: #ffffff; ">insert into SeqTab values(0,1);</span><span style="font-family: Verdana; ">&nbsp; &nbsp; &nbsp; &nbsp; //初始化，假设一个业务编号为1</span><span style="font-family: Verdana, Arial; font-size: 13px; line-height: 19px; background-color: #ffffff; "><br /></span>&nbsp; &nbsp;<span style="font-family: Verdana; font-size: 13px; line-height: 19px; background-color: yellow; ">update SeqTab set iSeqNo=last_insert_id(iSeqNo+1) where iSeqType=1;<br /></span>&nbsp; &nbsp;<span style="font-family: Verdana; font-size: 13px; line-height: 19px; background-color: yellow; ">select last_insert_id();</span><span style="font-family: Verdana; ">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;//这两句是获取一个业务的唯一ID，供业务进程使用。</span><br /><span style="font-family: Verdana; ">&nbsp; &nbsp;其实说到这张表，关键是说LAST_INSERT_ID()这个方法。它有两种形式LAST_INSERT_ID()，LAST_INSERT_ID(expr)。</span><br /><span style="font-family: Verdana; ">&nbsp; &nbsp;这个东西的特点是，1.属于每个CONNECTION，CONNECTION之间相互不会影响 2.不属于某个具体的表 3.返回最后一次INSERT AUTO_INCREMENT的值 4.假如以此使用INSERT插入 &nbsp; &nbsp;多行数据，只返回第一行数据产生的值 5.如果你UPDATE某个</span><span style="font-family: Verdana; ">AUTO_INCREMENT的值，不会影响</span><span style="font-family: Verdana; ">LAST_INSERT_ID()返回值</span><br />&nbsp; &nbsp;<span style="font-family: Verdana; ">LAST_INSERT_ID(expr)与</span><span style="font-family: Verdana; ">LAST_INSERT_ID()稍有不同，首先它返回expr的值，其次它的返回值会记录在</span><span style="font-family: Verdana; ">LAST_INSERT_ID()。</span><br /><span style="font-family: Verdana; ">&nbsp; &nbsp;我们这里主要使用到了第一和第二个特点，每个进程并发执行</span><span style="font-family: Verdana; font-size: 13px; line-height: 19px; background-color: #ffff00; ">update SeqTab set iSeqNo=last_insert_id(iSeqNo+1) where iSeqType=1;<span style="background-color: #ffffff; ">,</span><span style="background-color: #ffffff; ">就获取属于进程自己的iSeqNo并且记录在&nbsp;</span></span><span style="font-family: Verdana; font-size: 13px; line-height: 19px; background-color: #ffff00; "><span style="background-color: #ffffff; ">LAST_INSERT_ID中，通过第二句取出该值。</span></span>&nbsp; &nbsp;<br /><span style="font-family: Verdana; ">&nbsp; &nbsp; 接着我们在比较下其他一些办法。</span><br /><span style="font-family: Verdana; ">&nbsp; &nbsp; 第一种是直接一张表，里面有一个ID字段，设置成AUTO_INCREMENT。这个的问题是每个业务ID不是连续的，是离散的。</span><br /><span style="font-family: Verdana; ">&nbsp; &nbsp; 第二种是使用GUID或者UUID，但是这个问题我个人觉得是效率上的差异，字符串没有数字的效率好，另外数字ID今后也可以拼接一些区信息，之后跨区的时候可以方便获取对象是哪个区的.</span><img src ="http://www.cppblog.com/yg2362/aggbug/196061.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/yg2362/" target="_blank">梨树阳光</a> 2012-12-06 23:01 <a href="http://www.cppblog.com/yg2362/archive/2012/12/06/196061.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>大区中分配玩家唯一ID的办法</title><link>http://www.cppblog.com/yg2362/archive/2012/12/05/196002.html</link><dc:creator>梨树阳光</dc:creator><author>梨树阳光</author><pubDate>Wed, 05 Dec 2012 03:54:00 GMT</pubDate><guid>http://www.cppblog.com/yg2362/archive/2012/12/05/196002.html</guid><wfw:comment>http://www.cppblog.com/yg2362/comments/196002.html</wfw:comment><comments>http://www.cppblog.com/yg2362/archive/2012/12/05/196002.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cppblog.com/yg2362/comments/commentRss/196002.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/yg2362/services/trackbacks/196002.html</trackback:ping><description><![CDATA[<div><span style="font-family: Verdana; ">Mysql中除了使用auto_increment字段作为自增序号以外 还有另外一种办法 可以提供唯一序列号并且可以由一张表完成对多个序列</span></div><div><span style="font-family: Verdana; ">要求的满足。</span></div><div></div><div><span style="font-family: Verdana; ">大致如下：</span></div><div><span style="font-family: Verdana; ">1.创建一个简单表&nbsp;</span></div><div><span style="font-family: Verdana; ">&nbsp; &nbsp;create table SeqTab</span></div><div><span style="font-family: Verdana; ">&nbsp; &nbsp;( iSeqNo int not null default 0,</span></div><div><span style="font-family: Verdana; ">&nbsp; &nbsp; &nbsp;iSeqType int not null default 0);</span></div><div></div><div><span style="font-family: Verdana; ">2.插入一调记录</span></div><div><span style="font-family: Verdana; ">&nbsp; &nbsp;insert into SeqTab values(0,13); &nbsp;// 0表示SeqNo初始值，13为SeqType，同一张表可对多个应用提供Seq序列服务</span></div><div></div><div><span style="font-family: Verdana; ">3.不管多进程 or 单进程对SeqTab表同时进行访问，使用一下方法获取序列号</span></div><div><span style="font-family: Verdana; ">&nbsp; &nbsp;1st-&gt;update SeqTab set iSeqNo=last_insert_id(iSeqNo+1) where iSeqType=13;</span></div><div><span style="font-family: Verdana; ">&nbsp; &nbsp;2nd-&gt;select last_insert_id();</span></div><div></div><div><span style="font-family: Verdana; ">4.因多进程对SeqTab同时访问，进行update SeqTab set iSeqNo=last_insert_id(iSeqNo+1);时，数据库保证了update的事务</span></div><div><span style="font-family: Verdana; ">完整性，且last_insert_id()是与当前mysql连接相关的，所以多进程同时使用时，也不会冲突。<br /><br /></span></div><img src ="http://www.cppblog.com/yg2362/aggbug/196002.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/yg2362/" target="_blank">梨树阳光</a> 2012-12-05 11:54 <a href="http://www.cppblog.com/yg2362/archive/2012/12/05/196002.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>mysql中文乱码解析</title><link>http://www.cppblog.com/yg2362/archive/2012/11/26/195711.html</link><dc:creator>梨树阳光</dc:creator><author>梨树阳光</author><pubDate>Mon, 26 Nov 2012 11:56:00 GMT</pubDate><guid>http://www.cppblog.com/yg2362/archive/2012/11/26/195711.html</guid><wfw:comment>http://www.cppblog.com/yg2362/comments/195711.html</wfw:comment><comments>http://www.cppblog.com/yg2362/archive/2012/11/26/195711.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cppblog.com/yg2362/comments/commentRss/195711.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/yg2362/services/trackbacks/195711.html</trackback:ping><description><![CDATA[&nbsp; &nbsp; &nbsp; <span style="font-family: Verdana; ">相信大家在开发后台的过程中都遇到过中文乱码的问题，今天我就来讲讲其中的原因。</span><br /><span style="font-family: Verdana; ">&nbsp; &nbsp; &nbsp; 我这建了3张表，test_latin1,test_utf8,test_gbk,表结构如下</span><br /><span style="font-family: Verdana; ">&nbsp; &nbsp; &nbsp;&nbsp;+-------+----------+------+-----+---------+-------+</span><div><span style="font-family: Verdana; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| Field | Type &nbsp; &nbsp; | Null | Key | Default | Extra |</span></div><div><span style="font-family: Verdana; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;+-------+----------+------+-----+---------+-------+</span></div><div><span style="font-family: Verdana; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| name &nbsp;| char(32) | YES &nbsp;| &nbsp; &nbsp; | NULL &nbsp; &nbsp;| &nbsp; &nbsp; &nbsp; |</span></div><div><span style="font-family: Verdana; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;+-------+----------+------+-----+---------+-------+</span><br /><br /><span style="font-family: Verdana; ">&nbsp; &nbsp; &nbsp; 我的前端是gbk的编码</span><br /><span style="font-family: Verdana; ">&nbsp; &nbsp; &nbsp; 执行下面的语句</span><br /><span style="font-family: Verdana; ">&nbsp; &nbsp; &nbsp; set names 'latin1'</span><br /><span style="font-family: Verdana; ">&nbsp; &nbsp; &nbsp; insert into test_latin1 set name='王';('王'字是GBK编码)</span><br /><span style="font-family: Verdana; ">&nbsp; &nbsp; &nbsp; select name from test_latin1;</span><br /><span style="font-family: Verdana; ">&nbsp; &nbsp; &nbsp; 结果是否为乱码？</span><br /><br /><span style="font-family: Verdana; ">&nbsp; &nbsp; &nbsp;&nbsp;执行下面的语句</span></div><span style="font-family: Verdana; ">&nbsp; &nbsp; &nbsp; set names 'gbk'</span><br /><span style="font-family: Verdana; ">&nbsp; &nbsp; &nbsp; insert into test_latin1 set name='王';('王'字是GBK编码)</span><br /><span style="font-family: Verdana; ">&nbsp; &nbsp; &nbsp; select name from test_latin1;</span><br /><span style="font-family: Verdana; ">&nbsp; &nbsp; &nbsp; 结果是否为乱码？</span><br /><br /><span style="font-family: Verdana; ">&nbsp; &nbsp; &nbsp;&nbsp;执行下面的语句</span><br /><span style="font-family: Verdana; ">&nbsp; &nbsp; &nbsp; set names 'latin1'</span><br /><span style="font-family: Verdana; ">&nbsp; &nbsp; &nbsp; insert into test_utf8 set name='王';('王'字是GBK编码)</span><br /><span style="font-family: Verdana; ">&nbsp; &nbsp; &nbsp; select name from&nbsp;test_utf8&nbsp;;</span><br /><span style="font-family: Verdana; ">&nbsp; &nbsp; &nbsp; 结果是否为乱码？</span><br /><br /><span style="font-family: Verdana; ">&nbsp; &nbsp; &nbsp; 我们举个例子，假设一个汉字的字符编码为0xFFFF，它在屏幕上能够正常显示，如果汉字存入数据库的时候和从数据库中取出的时候，编码一致，那么它肯定不是乱码。反过来，如果输出的时候是乱码，那么它肯定被转码了，至于为什么被转码了，我们得看看mysql里面做了什么(mysql难道会把无码片变成了有码片？)</span><br /><span style="font-family: Verdana; ">&nbsp; &nbsp; &nbsp; 首先mysql里面有2个概念，一个叫character set,一个叫collation。我们先说说character set。字符集就是数字，英文字符，汉字等编码格式，我们常见的是utf8,gbk,gb2312。mysql里面比较复杂，有4个东西跟它有关，分别是character_set_client，character_set_connection，character_set_database，character_set_results。set names (latin1)其实就是character_set_client=latin1，character_set_connection=latin1，character_set_results=latin1，它的流程是character_set_client ==&gt;&nbsp;character_set_connection ==&gt; Table Character ==&gt;&nbsp;character_set_results。</span><br /><span style="font-family: Verdana; ">&nbsp; &nbsp; &nbsp; 我们按照上面的流程，来分析第一个问题。</span><br /><span style="font-family: Verdana; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;set names 'latin1'----执行了character_set_client=latin1，character_set_connection=latin1，character_set_results=latin1;</span><br /><span style="font-family: Verdana; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;insert into test_latin1 set name='王';这句话，mysql做了什么事呢？首先，character_set_client,它会把王字的编码当成latin1的编码传递给character_set_connection（此时不会转码），character_set_connection会把编码传递给Table Character,因为表本身是latin1，所以此时也不需要转码，select name from test_latin1;mysql会把test_latin1中的编码传递给前端，此时也不需要转码，所以，走个流程下来，我们输入的是什么编码，输出的还是相同的编码，因此，第一个问题的答案是不会是乱码。我画个流程图latin1==&gt;latin1==&gt;latin1==&gt;latin1,没有转码的过程</span><br />&nbsp; &nbsp; &nbsp;&nbsp;<br /><span style="font-family: Verdana; ">&nbsp; &nbsp; &nbsp; 我们在来看第二个问题。</span><br /><span style="font-family: Verdana; ">&nbsp; &nbsp; &nbsp;&nbsp;set names 'test_gbk'----执行了character_set_client=gbk，character_set_connection=gbk，character_set_results=gbk;</span><br /><span style="font-family: Verdana; ">&nbsp; &nbsp; &nbsp;&nbsp;insert into test_latin1 set name='王';character_set_client,它会把王字的编码当成gbk的编码传递给character_set_connection（此时不会转码）,character_set_connection会把编码传递给Table Character,因为表是lanti1的编码格式，这个过程的时候就会进行转码，但是latin1的字符集小于gbk的字符集，所以它会找不到对应字符的编码，此时会以？代替。select name from test_latin1，此时会从latin1转码成gbk,但是此时latin1已经是错误的数据了，所以得到的gbk编码也是错误的了。流程gbk==&gt;gbk==&gt;latin1==&gt;gbk,其中gbk==&gt;latin1出了问题，我们select出来的数据也就不可能是输入时候的数据了。因此，这个问题的答案是乱码。</span><br /><br /><span style="font-family: Verdana; ">&nbsp; &nbsp; &nbsp; 第三个。</span><br /><span style="font-family: Verdana; ">&nbsp; &nbsp; &nbsp;&nbsp;set names 'test_latin1'</span><br /><span style="font-family: Verdana; ">&nbsp; &nbsp; &nbsp;&nbsp;insert into test_utf8 set name='王';character_set_client,它会把王字的编码当成latin1的编码传递给character_set_connection（此时不会转码）,character_set_connection会把编码传递给Table Character,此时表是utf8的格式，因此会进行转码，latin1==&gt;utf8,因为utf8的字符集&gt;latin1字符集，因此，转码正常。select name from test_utf8;会从utf8转码成latin1,此时可以转码成功，因此我们最终得到的和输入的时候是一致的，因此答案不是乱码。流程latin1==&gt;latin1==&gt;utf8==&gt;latin1,从小的字符集到大的字符集再到小的字符集，转码是不会有问题的。</span><br /><span style="font-family: Verdana; ">&nbsp; &nbsp; &nbsp; 屁话了这么多，无非想告诉大家一个万精油方法，</span><strong style="font-family: Verdana; font-size: 14.399999618530273px; line-height: 23.200000762939453px; background-color: #ffffff; ">表创建的字符集和set&nbsp;names都设置成同一个字符集，就基本可以满足输入数据不会在转换过程中失真</strong><span style="font-family: Verdana; font-size: 14.399999618530273px; line-height: 23.200000762939453px; background-color: #ffffff; ">，也就是说输入是什么，输出就是什么。</span><strong style="font-family: Verdana; font-size: 14.399999618530273px; line-height: 23.200000762939453px; background-color: #ffffff; ">建议有中文的都设置成utf8字符集，一劳永逸。</strong><img src ="http://www.cppblog.com/yg2362/aggbug/195711.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/yg2362/" target="_blank">梨树阳光</a> 2012-11-26 19:56 <a href="http://www.cppblog.com/yg2362/archive/2012/11/26/195711.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>转发一篇LOL匹配规则</title><link>http://www.cppblog.com/yg2362/archive/2012/11/09/194977.html</link><dc:creator>梨树阳光</dc:creator><author>梨树阳光</author><pubDate>Fri, 09 Nov 2012 06:20:00 GMT</pubDate><guid>http://www.cppblog.com/yg2362/archive/2012/11/09/194977.html</guid><wfw:comment>http://www.cppblog.com/yg2362/comments/194977.html</wfw:comment><comments>http://www.cppblog.com/yg2362/archive/2012/11/09/194977.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/yg2362/comments/commentRss/194977.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/yg2362/services/trackbacks/194977.html</trackback:ping><description><![CDATA[<p align="left" style="word-wrap: break-word; margin: 0px; padding: 0px; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; ">这是Riot的Design Director Tom Cadwell专门为中国玩家写的讲解匹配系统工作原理的帖子。</p><p align="left" style="word-wrap: break-word; margin: 0px; padding: 0px; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; "><br style="word-wrap: break-word; " /></p><p align="left" style="word-wrap: break-word; margin: 0px; padding: 0px; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; ">同时为了让大家更好的理解匹配系统，如果您觉得您遇到了特别不公平的匹配，请回复游戏开始时间和比赛结束截图，我们会调查该局匹配是如何完成的，坑爹的玩家是为何加入到这一局的。</p><p align="left" style="word-wrap: break-word; margin: 0px; padding: 0px; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; "><br style="word-wrap: break-word; " /></p><p align="left" style="word-wrap: break-word; margin: 0px; padding: 0px; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; "><strong style="word-wrap: break-word; ">很多人抱怨看不懂，我来个精简比喻版的：</strong></p><p align="left" style="word-wrap: break-word; margin: 0px; padding: 0px; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; ">有个篮球联盟，有无数个球员和大概20个等级的联赛。</p><p align="left" style="word-wrap: break-word; margin: 0px; padding: 0px; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; "><br style="word-wrap: break-word; " /></p><p align="left" style="word-wrap: break-word; margin: 0px; padding: 0px; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; ">所有球员都是10级联赛的成员，他们自由组合互相比赛，赢的人，升级到11级联赛，输的人降到9级联赛。</p><p align="left" style="word-wrap: break-word; margin: 0px; padding: 0px; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; "><br style="word-wrap: break-word; " /></p><p align="left" style="word-wrap: break-word; margin: 0px; padding: 0px; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; ">然后每个等级联赛再次开赛，又有的人升级有的人降级，最终这20级的联赛都有球员参加。</p><p align="left" style="word-wrap: break-word; margin: 0px; padding: 0px; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; "><br style="word-wrap: break-word; " /></p><p align="left" style="word-wrap: break-word; margin: 0px; padding: 0px; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; ">我们的大量的数据证明，一个球员的水平，会让其稳定在大约3个联赛之间，也就是科比是参加20级联赛的，且当他和4个17级联赛的人组队，基本不会输给17级联赛的人。且，把科比降到10级联赛，他会轻松的在20局之内回到20级。</p><p align="left" style="word-wrap: break-word; margin: 0px; padding: 0px; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; "><br style="word-wrap: break-word; " /></p><p align="left" style="word-wrap: break-word; margin: 0px; padding: 0px; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; ">理想情况下，球员都是在跟自己同样经历的球员玩，一个中等水平玩家完全不会匹配到科比，科比也不会匹配到刚玩游戏的玩家。</p><p align="left" style="word-wrap: break-word; margin: 0px; padding: 0px; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; "><br style="word-wrap: break-word; " /></p><p align="left" style="word-wrap: break-word; margin: 0px; padding: 0px; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; ">事实上匹配系统的分级会比这个更复杂更智能，采用的是国际象棋所采用的elo系统。</p><p align="left" style="word-wrap: break-word; margin: 0px; padding: 0px; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; "><br style="word-wrap: break-word; " /></p><p align="left" style="word-wrap: break-word; margin: 0px; padding: 0px; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; "><strong style="word-wrap: break-word; ">再增加个FAQ：</strong></p><p align="left" style="word-wrap: break-word; margin: 0px; padding: 0px; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; ">Q：系统为了保持胜率50%，是否会在我连胜后故意塞给我一些菜队友让我输？</p><p align="left" style="word-wrap: break-word; margin: 0px; padding: 0px; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; ">A：系统的目的不是为了保持你的胜率，而是让水平差不多的玩家一起玩。当你和水平差不多的玩家一起玩时胜率会趋近50%，所以，系统是不会故意坑你的。</p><p align="left" style="word-wrap: break-word; margin: 0px; padding: 0px; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; "><br style="word-wrap: break-word; " /></p><p align="left" style="word-wrap: break-word; margin: 0px; padding: 0px; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; ">Q：我才100胜，为什么系统老匹配600胜的玩家给我？</p><p align="left" style="word-wrap: break-word; margin: 0px; padding: 0px; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; ">A：胜场并不能反应一个人的水平。如果把匹配系统比作跑步，练习了3年才能跑进11秒的和第一次就跑进11秒的人我们是同等看待的。匹配系统基于水平而不是基于经验。</p><p align="left" style="word-wrap: break-word; margin: 0px; padding: 0px; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; "><br style="word-wrap: break-word; " /></p><p align="left" style="word-wrap: break-word; margin: 0px; padding: 0px; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; ">Q：我胜率60%，为什么匹配40%胜率的队友、60%胜率的对手给我？</p><p align="left" style="word-wrap: break-word; margin: 0px; padding: 0px; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; ">A：胜率也不能反映水平。匹配系统不但要看你是否赢了，也要看你赢了谁。就像war3的sky在职业圈胜率其实并不高，但是虐一般的玩家胜率是100%。同样水平的玩家，会因为随机匹配到对手的关系，胜率会40%~60%不等。</p><p align="left" style="word-wrap: break-word; margin: 0px; padding: 0px; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; "><br style="word-wrap: break-word; " /></p><p align="left" style="word-wrap: break-word; margin: 0px; padding: 0px; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; ">Q：你说水平差不多，为什么我觉得他们这么菜？</p><p align="left" style="word-wrap: break-word; margin: 0px; padding: 0px; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; ">A：<strong style="word-wrap: break-word; ">匹配系统提供的是公平的机会，而未必是你理想的结果。</strong><strong style="word-wrap: break-word; ">我们能追求系统公正，但是无法预测玩家单局内的表现。</strong></p><p align="left" style="word-wrap: break-word; margin: 0px; padding: 0px; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; ">系统100%匹配曼联对阵皇马，但是不能保证某一次曼联不会4：0碾压皇马，且在这局中，C罗表现yts，完全就在拖后腿。或者曼联也可能连胜皇马3次之类的。但是，系统只会把曼联去匹配皇马而不会出现曼联对阵中超深圳队。具体到某一局是皇马赢还是曼联赢取决于那一场的排兵布阵，临场发挥，以及战术意图。<br style="word-wrap: break-word; " /></p><p align="left" style="word-wrap: break-word; margin: 0px; padding: 0px; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; "><br style="word-wrap: break-word; " /></p><p align="left" style="word-wrap: break-word; margin: 0px; padding: 0px; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; ">如果这个坑爹玩家真的不在你的水平等级，他就会一直坑队友，一直输，等级一直降低，这样会让他离开你的匹配范围，让他不再可以和你匹配到。根据我们的数据，玩家的elo基本是稳定在较小范围内的。这也就是深圳队和皇马的差距，也是中国国家队能赢法国队，确永远打不进世界杯的理由。</p><p align="left" style="word-wrap: break-word; margin: 0px; padding: 0px; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; "><br style="word-wrap: break-word; " /></p><p align="left" style="word-wrap: break-word; margin: 0px; padding: 0px; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; ">系统没办法给你完美队友，玩家会因为很多原因发挥不好：使用不会的英雄、打了不想打的位置、玩法风格和队友不够搭配，前期不利想挂机等等。但是你和对方玩家遇到这种情况的概率是相同的，系统并不会偏袒任何一方。所以想要完美队友，请和朋友组队，不过那样你也会碰见更厉害的对手。</p><p align="left" style="word-wrap: break-word; margin: 0px; padding: 0px; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; "><br style="word-wrap: break-word; " /></p><p align="left" style="word-wrap: break-word; margin: 0px; padding: 0px; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; "><strong style="word-wrap: break-word; ">如果大家在如何鉴定玩家水平上有好的想法欢迎提，但是如果想要通过抱怨玩家游戏内表现来证明匹配系统不公平，就是在和风车决斗了。每个人的看法都不一样的，系统判断他和你在遇到同样的队友和对手时候，胜率差不多，这也是我们目前能做到最好的了。</strong></p><p align="left" style="word-wrap: break-word; margin: 0px; padding: 0px; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; "><br style="word-wrap: break-word; " /></p><p align="left" style="word-wrap: break-word; margin: 0px; padding: 0px; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; "><br style="word-wrap: break-word; " /></p><p align="left" style="word-wrap: break-word; margin: 0px; padding: 0px; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; "><br style="word-wrap: break-word; " /></p><p align="left" style="word-wrap: break-word; margin: 0px; padding: 0px; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; ">以下是文章的正文。</p><p align="left" style="word-wrap: break-word; margin: 0px; padding: 0px; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; "><br style="word-wrap: break-word; " /></p><p align="left" style="word-wrap: break-word; margin: 0px; padding: 0px; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; "><strong style="word-wrap: break-word; ">概述：</strong></p><p align="left" style="word-wrap: break-word; margin: 0px; padding: 0px; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; ">匹配系统的目的如下，优先级从高到低：</p><br style="word-wrap: break-word; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; " /><p align="left" style="word-wrap: break-word; margin: 0px; padding: 0px; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; ">1、&nbsp;&nbsp;保护新手不被有经验的玩家虐；让高手局中没有新手。</p><p align="left" style="word-wrap: break-word; margin: 0px; padding: 0px; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; ">2、&nbsp;&nbsp;创造竞技和公平的游戏对局，使玩家的游戏乐趣最大化。</p><p align="left" style="word-wrap: break-word; margin: 0px; padding: 0px; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; ">3、&nbsp;&nbsp;无需等待太久就能找到对手进入游戏。</p><br style="word-wrap: break-word; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; " /><br style="word-wrap: break-word; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; " /><p align="left" style="word-wrap: break-word; margin: 0px; padding: 0px; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; ">匹配系统尽其所能的匹配水平接近的玩家，玩家的水平是来自他们在此之前赢了谁以及他们对手的水平。当你战胜对手，系统会认为你更强，当你输给对手，系统会认为你更弱。虽然这对于某一局游戏并不是那么的公平，但是长期来看，对于多局游戏是相当的公平：因为好的玩家总会对游戏结果造成正面的、积极的影响。我们使用了这样一个方法测试：给水平高的玩家一个新帐号，然后看他们游戏数局后的结果。我们通过大量的测试来证明了我们的想法。</p><br style="word-wrap: break-word; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; " /><br style="word-wrap: break-word; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; " /><p align="left" style="word-wrap: break-word; margin: 0px; padding: 0px; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; ">并且，匹配系统知道预先组队的玩家有一些优势，如果你是预先组队，会给你一些更强的玩家。我们用一些非常巧妙的数学方法来解决预先组队的玩家VS solo玩家的匹配公平问题。我甚至让两个数学博士来验证，他们都说给力！</p><br style="word-wrap: break-word; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; " /><br style="word-wrap: break-word; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; " /><p align="left" style="word-wrap: break-word; margin: 0px; padding: 0px; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; "><strong style="word-wrap: break-word; ">匹配是怎么完成的？</strong></p><br style="word-wrap: break-word; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; " /><p align="left" style="word-wrap: break-word; margin: 0px; padding: 0px; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; ">首先，系统将你放进适当的匹配池里&#8212;&#8212;根据游戏模式（匹配模式、排位solo/双人、排位5人、其他模式等等）</p><br style="word-wrap: break-word; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; " /><p align="left" style="word-wrap: break-word; margin: 0px; padding: 0px; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; ">然后，系统会尝试将匹配池里的人分到更细的匹配池里&#8212;&#8212;5人组队 VS 5人组队，低等级新手 vs 其他一些低等级新手，如此这般。</p><br style="word-wrap: break-word; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; " /><p align="left" style="word-wrap: break-word; margin: 0px; padding: 0px; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; ">当你在匹配池中，系统会开始尝试找到合适的配对，目标是撮合一个双方获胜机会都为50%的游戏。</p><br style="word-wrap: break-word; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; " /><br style="word-wrap: break-word; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; " /><p align="left" style="word-wrap: break-word; margin: 0px; padding: 0px; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; ">第1步：确定你的实力：</p><br style="word-wrap: break-word; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; " /><p align="left" style="word-wrap: break-word; margin: 0px; padding: 0px; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; ">*如果你是solo，就直接使用你的个人匹配分（也就是elo值，匹配模式和排位赛有不同的匹配分）</p><p align="left" style="word-wrap: break-word; margin: 0px; padding: 0px; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; ">*如果你是预先组队的，你的匹配分是你队伍的平均分，并且会根据你组队的规模稍微提高一些，这样才能保证你匹配到更强的对手来抵消你组队的优势。我和一个计算机生物学的博士（Computational Biology Ph.D）通过研究成百上千的游戏结果，计算出了预先组队到底有多大的优势。我们还在幕后做了一些其他调整，比如新手和高玩组队，比如某地图上蓝队和紫队的玩家哪个更有优势，诸如此类。</p><br style="word-wrap: break-word; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; " /><br style="word-wrap: break-word; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; " /><p align="left" style="word-wrap: break-word; margin: 0px; padding: 0px; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; ">第2步：确定你合适的对手：</p><br style="word-wrap: break-word; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; " /><p align="left" style="word-wrap: break-word; margin: 0px; padding: 0px; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; ">*首先，系统会基于你的elo值，给你匹配跟你非常相近的玩家。最终，系统会放宽匹配的条件，给你一些不是那么完美的匹配，因为你肯定也不想永远匹配不到人。</p><p align="left" style="word-wrap: break-word; margin: 0px; padding: 0px; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; ">*新手会得到一些特殊的保护，通常新手只会匹配到其他新手（在成熟的服务器里，这个比例达到了99%+。除非这个新手和一个高级玩家朋友预先组队）</p><br style="word-wrap: break-word; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; " /><br style="word-wrap: break-word; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; " /><p align="left" style="word-wrap: break-word; margin: 0px; padding: 0px; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; ">第3步：确定匹配：</p><br style="word-wrap: break-word; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; " /><p align="left" style="word-wrap: break-word; margin: 0px; padding: 0px; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; ">*最终，系统会匹配10个大体上同水平、同等级的玩家，促成一个游戏。</p><p align="left" style="word-wrap: break-word; margin: 0px; padding: 0px; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; ">*系统会尝试平衡这个队伍，尽量使双方的获胜机会都为50%。在绝大多数时间，误差会在3%之内&#8212;&#8212;类似50/50，49/51，48/52。实际上的获胜机会会有一点点差别（会在Q&amp;A里面回答这个问题），但是我们的研究标明，在绝大多数情况下，这实际上是一个非常精确的预测。</p><br style="word-wrap: break-word; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; " /><br style="word-wrap: break-word; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; " /><p align="left" style="word-wrap: break-word; margin: 0px; padding: 0px; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; "><strong style="word-wrap: break-word; ">长期来讲，我的匹配分（Elo</strong><strong style="word-wrap: break-word; ">值）是如何被测量的？</strong></p><p align="left" style="word-wrap: break-word; margin: 0px; padding: 0px; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; ">我们使用了一个修改过的ELO系统。ELO系统的基本要点通过使用数学比较两个人的积分，来预测两人的比赛结果&#8212;&#8212;类似&#8220;A和B比赛数局，A会赢掉75%的局&#8221;。</p><br style="word-wrap: break-word; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; " /><br style="word-wrap: break-word; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; " /><p align="left" style="word-wrap: break-word; margin: 0px; padding: 0px; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; ">然后，比赛结果出来了。如果你赢了，你会加分，如果你输了，你会被扣分。如果你是&#8220;出人意料&#8221;的赢了（系统认为你输的可能性更大），你会赢得更多的分数。额外的，如果你是一个新玩家，你会加分减分更快，以便于你可以快速的进入到你的水平等级。长期来看，这意味着好的玩家会得到高的匹配分，因为他们总是超过系统的预期，他们会不断加分直到系统可以正确的预测他们的胜率。</p><br style="word-wrap: break-word; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; " /><br style="word-wrap: break-word; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; " /><p align="left" style="word-wrap: break-word; margin: 0px; padding: 0px; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; ">我们修改这个系统给团队比赛使用，基本概念是：基于该团队的所有玩家，得到一个团队ELO值。如果你的队伍胜利，系统会假设该队伍的所有玩家都要比系统猜测的&#8220;更强&#8221;，并且加分。虽然有一些问题，但是总体上来讲是有效的，特别是玩家预先组队的时候。</p><br style="word-wrap: break-word; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; " /><br style="word-wrap: break-word; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; " /><p align="left" style="word-wrap: break-word; margin: 0px; padding: 0px; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; ">举例，本人在北美的服务器上有2000的普通匹配模式elo。如果我建一个小号，就算没有天赋和符文，我打到8级的时候就已经有1800elo了。这个系统并不完美，但是确实能够让玩家快速的接近自己水平所在的位置。</p><br style="word-wrap: break-word; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; " /><br style="word-wrap: break-word; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; " /><p align="left" style="word-wrap: break-word; margin: 0px; padding: 0px; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; ">当你才开始玩的时候，我们也对ELO做一些微调，让你更快的进入你水平所在的位置。</p><p align="left" style="word-wrap: break-word; margin: 0px; padding: 0px; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; ">*我们有大量的，有优先级的方法来鉴定一个玩家，相比一个标准的新玩家是否更有技巧，更猛。如果发现是的，我们会在幕后提高他的elo一个档次。</p><p align="left" style="word-wrap: break-word; margin: 0px; padding: 0px; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; ">*我们同样也会分辨真的菜鸟新手。</p><p align="left" style="word-wrap: break-word; margin: 0px; padding: 0px; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; ">*提升等级也会极大的提高你的elo值。这个也将帮助系统将30级满级的召唤师和低等级的召唤师区分开来</p><br style="word-wrap: break-word; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; " /><br style="word-wrap: break-word; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; " /><p align="left" style="word-wrap: break-word; margin: 0px; padding: 0px; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; ">如果你想知道ELO系统的理论，以及更多细节，你可以看看这：</p><p align="left" style="word-wrap: break-word; margin: 0px; padding: 0px; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; "><a href="http://en.wikipedia.org/wiki/Elo_rating_system" target="_blank" style="word-wrap: break-word; color: #336699; ">http://en.wikipedia.org/wiki/Elo_rating_system</a></p><p align="left" style="word-wrap: break-word; margin: 0px; padding: 0px; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; "><a href="http://zh.wikipedia.org/wiki/ELO" target="_blank" style="word-wrap: break-word; color: #336699; ">http://zh.wikipedia.org/wiki/ELO</a></p><br style="word-wrap: break-word; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; " /><br style="word-wrap: break-word; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; " /><p align="left" style="word-wrap: break-word; margin: 0px; padding: 0px; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; "><strong style="word-wrap: break-word; ">呃，等等，你是怎么处理组队玩家 vs solo(</strong><strong style="word-wrap: break-word; ">单排)</strong><strong style="word-wrap: break-word; ">玩家的？</strong></p><p align="left" style="word-wrap: break-word; margin: 0px; padding: 0px; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; ">我们大多数情况下，会通过将5人组队的队伍匹配给另外一个5人组队的队伍来避免这种情况的发生（几乎是所有情况下）。</p><br style="word-wrap: break-word; " /><br style="word-wrap: break-word; " />对于&#8220;部分&#8221;组队，我们进行了大量的研究，发现优势并没有想象的那么大，所以我们也会把他们混到solo（单排）的玩家里。我们发现有大量的因素会影响到组队优势的大小：从预先组队的规模（比如2、3、4、5组队），到组队玩家的水平，到高玩带菜鸟的组合，到玩家水平不同而导致的情况不同，以及其他的一些必须考虑到的微妙因素。这个要比一些我们曾见过的点对点算法-将任意的统计数据杂糅在一起猜测分数-要可靠的多&nbsp;<br style="word-wrap: break-word; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; " /><p align="left" style="word-wrap: break-word; margin: 0px; padding: 0px; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; ">发现这些优势，我们就知道对于预先组队的队伍，需要提高多少elo值，来达成一个公平的匹配，确定一个适当的，在数学上合理的调整。结果在有些情况下非常令人惊讶（同时会校正统计数据）。</p><br style="word-wrap: break-word; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; " /><br style="word-wrap: break-word; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; " /><p align="left" style="word-wrap: break-word; margin: 0px; padding: 0px; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; ">虽然我们不会给出精确的数值，因为这是商业机密，但是我们可以告诉您：</p><p align="left" style="word-wrap: break-word; margin: 0px; padding: 0px; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; ">*5人组队只是比5个路人稍强。</p><p align="left" style="word-wrap: break-word; margin: 0px; padding: 0px; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; ">*部分组队只是比5个路人略强。</p><p align="left" style="word-wrap: break-word; margin: 0px; padding: 0px; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; ">*菜鸟5人组队并不会带来太大的优势，但是高玩组队会有很大的优势。</p><p align="left" style="word-wrap: break-word; margin: 0px; padding: 0px; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; ">*团队实力方差高的队伍，会比方差低的队伍更强。（方差简单来说，是在平均值相同的情况下反应各个元素的大小差异，方差大表示差异大，高方差的队伍类似高玩带低玩，低方差的队伍各个队员实力接近。）</p><p align="left" style="word-wrap: break-word; margin: 0px; padding: 0px; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; ">*这说明了大体上，高水平玩家的Carry作用（可以理解为带领或者大腿），比低水平玩家的送人头作用（feeder）要强力。</p><br style="word-wrap: break-word; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; " /><br style="word-wrap: break-word; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; " /><p align="left" style="word-wrap: break-word; margin: 0px; padding: 0px; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; "><strong style="word-wrap: break-word; ">好吧&#8230;</strong><strong style="word-wrap: break-word; ">那为什么要把预先组队的玩家和非组队玩家匹配到一起？</strong></p><p align="left" style="word-wrap: break-word; margin: 0px; padding: 0px; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; ">这是一些原因：</p><br style="word-wrap: break-word; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; " /><p align="left" style="word-wrap: break-word; margin: 0px; padding: 0px; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; ">*这会帮助系统更快的找到适合你的匹配分，让系统更快的给你公平的匹配。这个的工作原理是，如果你组队，会减低运气所带来的成分，如果你单排，你的队友的好坏将对你输赢的影响更大。如果你预先组队，你会和你水平差不多的玩家组成队伍，你随机遇到猛男/坑爹队友几率会更小。因为游戏的结果更多来自你和水平相近的朋友的表现，而不是随机因素，所以你的匹配分会更快的到达精确的值。</p><p align="left" style="word-wrap: break-word; margin: 0px; padding: 0px; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; ">*我们希望玩家可以和自己的朋友一起玩，因为这样会让他们玩的更有乐趣。你也不可能为5v5的游戏设置单独的2人匹配池或者3人匹配池，你需要组合他们来让系统工作。我们选择包含5人组队，因为这非常有乐趣。如果我们以后有足够大的匹配池，我们可能会将5人组队和部分组队区分开来，但是数据告诉我们，这基本不会提升匹配的公平程度，两者的效果基本相同。</p><br style="word-wrap: break-word; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; " /><br style="word-wrap: break-word; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; " /><p align="left" style="word-wrap: break-word; margin: 0px; padding: 0px; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; "><strong style="word-wrap: break-word; ">其他一些常见的问题：</strong></p><br style="word-wrap: break-word; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; " /><p align="left" style="word-wrap: break-word; margin: 0px; padding: 0px; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; "><strong style="word-wrap: break-word; ">Q</strong><strong style="word-wrap: break-word; ">：</strong>为什么不加入一些其他的细节，类似击杀数等等来确定我的匹配分？</p><p align="left" style="word-wrap: break-word; margin: 0px; padding: 0px; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; "><strong style="word-wrap: break-word; ">A</strong><strong style="word-wrap: break-word; ">：</strong>因为这是有偏差的，并且因为非常难以给击杀数这个数值来评分，你使用一个gank英雄的时候（类似老鼠和易大师），要杀多少人才能算是好的呢？而且这会让好的辅助玩家非常吃亏，因为他们的目的就不是拿人头，甚至会为了自己的Carry挡死。最后，玩家会为了刷数据，故意拖长游戏时间，然后拿大量farm对方的人头，而不是为了赢得比赛。我们尽量把测量玩家水平和激励玩家的机制放到努力取胜上面，我们避免了一些不必要的周边行为，而这些行为既没乐趣，还会扰乱匹配系统。</p><br style="word-wrap: break-word; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; " /><br style="word-wrap: break-word; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; " /><p align="left" style="word-wrap: break-word; margin: 0px; padding: 0px; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; "><strong style="word-wrap: break-word; ">Q</strong><strong style="word-wrap: break-word; ">：</strong>我非常愤怒，因为匹配系统老给我坑爹队友（feeders，送人头的）。为什么不阻止这种情况发生？</p><p align="left" style="word-wrap: break-word; margin: 0px; padding: 0px; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; "><strong style="word-wrap: break-word; ">A</strong><strong style="word-wrap: break-word; ">：</strong>我们的确有试图阻止这种情况发生，但是如果你被匹配到一个明显很弱的玩家，这也说明匹配系统同时匹配给你了一个或者多个强力的玩家。根据我们的研究，我们发现Carry（大腿）对队伍的带领作用要比feeder（送人头，坑爹）的坑爹作用更强。原因是在LOL里，多次击杀同一个玩家的收益是会递减的，并不像其他的同类游戏。我们的分析标明，在平均elo相同的情况下，提高或者降低这个队伍的某个玩家的elo值100（其他玩家相应降低/提高以保持平均分相同），整个队伍的实力会提高约7点elo值。这也表明，LOL中Carry的作用要比feeder的作用更给力一些。确实，有时候你会因为匹配到feeder而输掉这一局比赛，但是那是因为你们队的Carry不够给力。</p><br style="word-wrap: break-word; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; " /><br style="word-wrap: break-word; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; " /><p align="left" style="word-wrap: break-word; margin: 0px; padding: 0px; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; "><strong style="word-wrap: break-word; ">Q</strong><strong style="word-wrap: break-word; ">：</strong>这样的话，如果我连胜了数盘，我是不是会被匹配到一些完全不可战胜的对手？</p><p align="left" style="word-wrap: break-word; margin: 0px; padding: 0px; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; "><strong style="word-wrap: break-word; ">A</strong><strong style="word-wrap: break-word; ">：</strong>不全是。连胜导致你的匹配分会提高，你会不断遇到更强的对手&#8212;&#8212;但是我们并不是故意的让你的胜率保持在50%的，我们的目的只是为了系统能够正确的预测游戏结果。最终，你会达到你的极限，你将会大致保持50%的胜率。比平均水平高的玩家，往往胜率会比50%略高，因为比他们弱的玩家更多，比他们强的玩家更少。所以匹配时，往往会略微&#8220;向下匹配&#8221;。对于排位顶尖的高端玩家，他们经常会有90%的胜率。</p><br style="word-wrap: break-word; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; " /><br style="word-wrap: break-word; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; " /><p align="left" style="word-wrap: break-word; margin: 0px; padding: 0px; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; "><strong style="word-wrap: break-word; ">Q</strong><strong style="word-wrap: break-word; ">：</strong>你们会如何设计固定的队伍？类似WOW的竞技场队伍？</p><p align="left" style="word-wrap: break-word; margin: 0px; padding: 0px; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; "><strong style="word-wrap: break-word; ">A</strong><strong style="word-wrap: break-word; ">：</strong>这是一个非常好的想法，并且让我们有机会设计出更好的匹配系统。我们迟早会做这个，并且使用我们开发的新方法。我们需要检验并且搞清楚你大体上有多强力（例如你的个人积分），同时允许你创建/解散队伍。这是个非常大的工程，但是我们对此非常有激情~</p><br style="word-wrap: break-word; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; " /><br style="word-wrap: break-word; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; " /><p align="left" style="word-wrap: break-word; margin: 0px; padding: 0px; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; "><strong style="word-wrap: break-word; ">Q</strong><strong style="word-wrap: break-word; ">：</strong>如果匹配系统真的那么公平，那为何我老遇见那种一边倒的比赛？</p><p align="left" style="word-wrap: break-word; margin: 0px; padding: 0px; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; "><strong style="word-wrap: break-word; ">A</strong><strong style="word-wrap: break-word; ">：</strong>有两个原因。第一，LOL有时候&#8220;雪球效应&#8221;会非常明显。前期太差的表现会导致游戏让人感觉非常一边倒。特别是某些队伍，如果他们开始很顺风，就会一直很顺风。我们遇到过同样的队伍，第一局25-5取胜，第2局确以类似的比分输掉。第二个原因是，玩家发挥的并不好，队伍选取阵容也不好。要进行一局势均力敌的比赛，你需要平衡玩家水平和平衡阵容的选取。有时候玩家选了一个比较渣的阵容，比如5个近战dps，或者3坦克2法师之类的，或者没选打野英雄而对面有。这样的话，尽管你的队伍实力也很不错，但是情况往往惨不忍睹。</p><br style="word-wrap: break-word; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; " /><br style="word-wrap: break-word; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; " /><p align="left" style="word-wrap: break-word; margin: 0px; padding: 0px; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; "><strong style="word-wrap: break-word; ">Q</strong><strong style="word-wrap: break-word; ">：</strong>为什么我作为一个高等级玩家，有时候会匹配到一些低等级玩家？他们看上去都是来送人头的。</p><p align="left" style="word-wrap: break-word; margin: 0px; padding: 0px; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; "><strong style="word-wrap: break-word; ">A</strong><strong style="word-wrap: break-word; ">：</strong>当一个高等级玩家和一个低等级玩家组队，这是一个非常令人头疼的问题。我们希望玩家可以和自己的朋友一起玩，并且希望这是一种愉快的体验。但是我们并不希望将一部分人的快乐建立在另一部分人的痛苦之上，所以我们往往将这种组合评分更高，保护新玩家不会被高等级玩家虐待。非常不幸的是，不管我们怎么做，我们把这样的组合匹配到任何的游戏中，都有可能造成不愉快的体验。因此，我们计划将实施一个&#8220;不平衡组队&#8221;的队列，类似我们尽量将5人组队匹配给5人组队。</p><br style="word-wrap: break-word; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; " /><br style="word-wrap: break-word; " /><p align="left" style="word-wrap: break-word; margin: 0px; padding: 0px; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; "><strong style="word-wrap: break-word; ">Q</strong><strong style="word-wrap: break-word; ">：</strong>我20级了，然后我被匹配到了一些10级的和一些29级的，怎么回事？</p><p align="left" style="word-wrap: break-word; margin: 0px; padding: 0px; color: #444444; font-family: Tahoma, 'Microsoft Yahei', Simsun; background-color: #ffffff; "><strong style="word-wrap: break-word; ">A</strong><strong style="word-wrap: break-word; ">：</strong>当不同等级的玩家组队，我们会使用他们的平均等级来作为匹配的参考。等级并不是匹配系统的主导参数&#8212;&#8212;匹配系统通常是使用实力来匹配&#8212;&#8212;但是我们也会尽量将等级相近的玩家匹配到一起。在预先组队的情况下，我们没法替玩家选择，所以我们尽我们所能，使用平均等级。我们会在这个计算系统里把30级的玩家看作36级，所以我们通常能让中等级玩家的游戏没有30级玩家，然而有时候呢，29级玩家能插进来。</p><img src ="http://www.cppblog.com/yg2362/aggbug/194977.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/yg2362/" target="_blank">梨树阳光</a> 2012-11-09 14:20 <a href="http://www.cppblog.com/yg2362/archive/2012/11/09/194977.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Linux切换用户路径显示</title><link>http://www.cppblog.com/yg2362/archive/2012/11/08/194866.html</link><dc:creator>梨树阳光</dc:creator><author>梨树阳光</author><pubDate>Thu, 08 Nov 2012 03:49:00 GMT</pubDate><guid>http://www.cppblog.com/yg2362/archive/2012/11/08/194866.html</guid><wfw:comment>http://www.cppblog.com/yg2362/comments/194866.html</wfw:comment><comments>http://www.cppblog.com/yg2362/archive/2012/11/08/194866.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/yg2362/comments/commentRss/194866.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/yg2362/services/trackbacks/194866.html</trackback:ping><description><![CDATA[<span style="font-family: Verdana; ">记录下这个小问题。root下可以显示路径但是切换到其他用户时没有路径显示，很不方便。</span><br /><span style="font-family: Verdana; ">在/etc/profile中加入</span><br /><div><span style="font-family: Verdana; ">export PS1='\u@\h:\w&gt;',</span><span style="background-color: #fffcf6; font-family: Verdana; line-height: 22px; white-space: pre-wrap; ">其中\u显示当前用户账号，\h显示当前主机名，\W显示当前路径。然后source一下就搞定了</span></div><img src ="http://www.cppblog.com/yg2362/aggbug/194866.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/yg2362/" target="_blank">梨树阳光</a> 2012-11-08 11:49 <a href="http://www.cppblog.com/yg2362/archive/2012/11/08/194866.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>两个小问题</title><link>http://www.cppblog.com/yg2362/archive/2012/10/01/192562.html</link><dc:creator>梨树阳光</dc:creator><author>梨树阳光</author><pubDate>Mon, 01 Oct 2012 07:53:00 GMT</pubDate><guid>http://www.cppblog.com/yg2362/archive/2012/10/01/192562.html</guid><wfw:comment>http://www.cppblog.com/yg2362/comments/192562.html</wfw:comment><comments>http://www.cppblog.com/yg2362/archive/2012/10/01/192562.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.cppblog.com/yg2362/comments/commentRss/192562.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/yg2362/services/trackbacks/192562.html</trackback:ping><description><![CDATA[<span style="font-family: Tahoma; ">开门见山，我先提出几个问题，大家可以先想想，然后我再说出我的方法<br />
1.如何判断一个数M是否为2的N次方？<br />
</span>2.一个数N，如何得到一个数是M，M是不小于N的最小2的K次方<br />
<br />
先说第一个问题，我有两个思路<br />
第一，可以通过判断M的二进制中1的个数。而判断M中1的个数可以通过下面方法获得<br />
<div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><span style="color: #0000ff; ">int</span>&nbsp;GetOneCnt(<span style="color: #0000ff; ">int</span>&nbsp;m)&nbsp;<br />{<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(&nbsp;m&nbsp;==&nbsp;0&nbsp;)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;0;<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;cnt&nbsp;=&nbsp;1;<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">while</span>(m&nbsp;&amp;&nbsp;(m-1))<br />
&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cnt++;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m--;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;cnt;<br />
}</div>很明显M中1的个数为1和M是2的N次方互为冲要条件<br />第二个思路，我们可以这样，还是利用M的二进制表示，从最高位开始，以变量high_pos表示第一个1的下标，接着从最低位开始，变量low_pos表示第一个1的下标，如果high_pos=low_pos,则M为2的N次方<br /><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #0000FF; ">int</span>&nbsp;HighestBitSet(<span style="color: #0000FF; ">int</span>&nbsp;input)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;register&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;result;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(input&nbsp;==&nbsp;0)<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;&nbsp;-1;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />#ifdef&nbsp;WIN32<br />&nbsp;&nbsp;&nbsp;&nbsp;_asm&nbsp;bsr&nbsp;eax,&nbsp;input<br />&nbsp;&nbsp;&nbsp;&nbsp;_asm&nbsp;mov&nbsp;result,&nbsp;eax<br /><span style="color: #0000FF; ">#else</span><br />&nbsp;&nbsp;&nbsp;&nbsp;asm("bsr&nbsp;%1,&nbsp;%%eax;"<br />&nbsp;&nbsp;&nbsp;&nbsp;"movl&nbsp;%%eax,&nbsp;%0"<br />&nbsp;&nbsp;&nbsp;&nbsp;:"=r"(result)<br />&nbsp;&nbsp;&nbsp;&nbsp;:"r"(input)<br />&nbsp;&nbsp;&nbsp;&nbsp;:"%eax");<br /><span style="color: #0000FF; ">#endif</span><br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;result;<br />}</div><div style="background-color: #eeeeee; font-size: 13px; border: 1px solid #cccccc; padding: 4px 5px 4px 4px; width: 98%; word-break: break-all; "><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #0000FF; ">int</span>&nbsp;LowestBitSet(<span style="color: #0000FF; ">int</span>&nbsp;input)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;register&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;result;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(input&nbsp;==&nbsp;0)<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;&nbsp;-1;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />#ifdef&nbsp;WIN32<br />&nbsp;&nbsp;&nbsp;&nbsp;_asm&nbsp;bsf&nbsp;eax,&nbsp;input<br />&nbsp;&nbsp;&nbsp;&nbsp;_asm&nbsp;mov&nbsp;result,&nbsp;eax<br /><span style="color: #0000FF; ">#else</span><br />&nbsp;&nbsp;&nbsp;&nbsp;asm("bsf&nbsp;%1,&nbsp;%%eax;"<br />&nbsp;&nbsp;&nbsp;&nbsp;"movl&nbsp;%%eax,&nbsp;%0"<br />&nbsp;&nbsp;&nbsp;&nbsp;:"=r"(result)<br />&nbsp;&nbsp;&nbsp;&nbsp;:"r"(input)<br />&nbsp;&nbsp;&nbsp;&nbsp;:"%eax");<br /><span style="color: #0000FF; ">#endif</span><br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;result;<br />}</div><br />再说第二个问题<br />其实有了第一个问题的思路，这个问题就更好解决了，先判断一个数是否为2^N，如果是，直接返回，否则返回2^(N+1)<br />代码如下<br /><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #0000FF; ">int</span>&nbsp;CeilingPowerOfTwo(<span style="color: #0000FF; ">int</span>&nbsp;iInput)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(iInput&nbsp;&lt;=&nbsp;1)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;&nbsp;1;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;int32_t&nbsp;highestBit&nbsp;=&nbsp;HighestBitSet(iInput);<br />&nbsp;&nbsp;&nbsp;&nbsp;int32_t&nbsp;mask&nbsp;=&nbsp;iInput&nbsp;&amp;&nbsp;((1&nbsp;&lt;&lt;&nbsp;highestBit)&nbsp;-&nbsp;1);&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;相当于input对2^highestBit求余</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;highestBit&nbsp;+=&nbsp;(&nbsp;mask&nbsp;&gt;&nbsp;0&nbsp;);<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;(1&lt;&lt;highestBit);<br />}</div><img src ="http://www.cppblog.com/yg2362/aggbug/192562.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/yg2362/" target="_blank">梨树阳光</a> 2012-10-01 15:53 <a href="http://www.cppblog.com/yg2362/archive/2012/10/01/192562.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Unicode和UTF-8的区别</title><link>http://www.cppblog.com/yg2362/archive/2012/09/23/191746.html</link><dc:creator>梨树阳光</dc:creator><author>梨树阳光</author><pubDate>Sun, 23 Sep 2012 14:56:00 GMT</pubDate><guid>http://www.cppblog.com/yg2362/archive/2012/09/23/191746.html</guid><wfw:comment>http://www.cppblog.com/yg2362/comments/191746.html</wfw:comment><comments>http://www.cppblog.com/yg2362/archive/2012/09/23/191746.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/yg2362/comments/commentRss/191746.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/yg2362/services/trackbacks/191746.html</trackback:ping><description><![CDATA[如果你对能很快回答出unicode和utf-8的关系，你可以直接跳过这篇文章。下面我来说说两者的关系和转换。（本文使用符号2字代表所有的汉字，英文，数字等）<br />首先明确一点，UTF-8是UNICODE一种实现方式。<br />UNICODE：代表一种符号集合，它规定了一种符合的二进制表示，没有指明存储方式。(<a href="http://www.unicode.org/">http://www.unicode.org/</a>)<br />UTF-8:实现了UNICODE，使用多字节的存储方式。<br />我们先来考虑几个问题。<br />第一，如果使用单字节表示符号，很明显，完全不够用<br />第二，如果使用多字节表示符号，那么，机器在读取的时候，它怎么知道3个字节表示一个符号，还是表示3个符号<br />第三，如果使用2个字节表示一个符号，首先，最多能表示65535个字符还是会不够用，就算够用，比如ASCII码这类仅需1个字节就可以表示的符号，用2个字节表示，浪费空间了。<br />因此，UTF-8孕育而生。<br />首先UTF-8使用变长表示符号，简单的说，有的时候用1个字节表示符号，有的时候用2个字节表示符号，这样解决了浪费空间的问题。那么，如何解决第二个问题的呢，我们得了解下UFT-8的编码规则。<br />1.对于单字节的符号，字节第一个为0，后面7为为这个符号的unicode码<br />2.对于N字节的符号(N&gt;1),第一个字节前N位为1，第N+1位为0，后面字节的前两位设为10,剩下可编码的位，为该符号的UNICODE编码。<br />这里我从网上找了一副图<br />&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #111111; font-family: 'Courier New', Courier, monospace; font-size: 16px; line-height: 28px; word-spacing: 2px; background-color: #e0dfcc; ">Unicode符号范围 | UTF-8编码方式</span><br style="color: #111111; font-family: 'Courier New', Courier, monospace; font-size: 16px; line-height: 28px; word-spacing: 2px; background-color: #e0dfcc; " />&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #111111; font-family: 'Courier New', Courier, monospace; font-size: 16px; line-height: 28px; word-spacing: 2px; background-color: #e0dfcc; ">(十六进制) | （二进制）</span><br style="color: #111111; font-family: 'Courier New', Courier, monospace; font-size: 16px; line-height: 28px; word-spacing: 2px; background-color: #e0dfcc; " /><span style="color: #111111; font-family: 'Courier New', Courier, monospace; font-size: 16px; line-height: 28px; word-spacing: 2px; background-color: #e0dfcc; ">0000 0000-0000 007F&nbsp;</span><span style="color: #111111; font-family: 'Courier New', Courier, monospace; font-size: 16px; line-height: 28px; word-spacing: 2px; background-color: #e0dfcc; ">| 0xxxxxxx</span><br style="color: #111111; font-family: 'Courier New', Courier, monospace; font-size: 16px; line-height: 28px; word-spacing: 2px; background-color: #e0dfcc; " /><span style="color: #111111; font-family: 'Courier New', Courier, monospace; font-size: 16px; line-height: 28px; word-spacing: 2px; background-color: #e0dfcc; ">0000 0080-0000 07FF | 110xxxxx 10xxxxxx</span><br style="color: #111111; font-family: 'Courier New', Courier, monospace; font-size: 16px; line-height: 28px; word-spacing: 2px; background-color: #e0dfcc; " /><span style="color: #111111; font-family: 'Courier New', Courier, monospace; font-size: 16px; line-height: 28px; word-spacing: 2px; background-color: #e0dfcc; ">0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx</span><br style="color: #111111; font-family: 'Courier New', Courier, monospace; font-size: 16px; line-height: 28px; word-spacing: 2px; background-color: #e0dfcc; " /><span style="color: #111111; font-family: 'Courier New', Courier, monospace; font-size: 16px; line-height: 28px; word-spacing: 2px; background-color: #e0dfcc; ">0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx<br /></span>下面我具体解释下这幅图。<br />首先看第一行，它的意思是00000000到0000007F的UNICODE编码，对应的UTF-8的编码方式为0XXXXXXX(X表示可编码位，不足的补0)。<br />第二行表示00000080到000007FF的UNICODE编码，对应的UTF-8的编码方式为110XXXXX 10XXXXXX。以此类推<br />那么，问题是，这个范围是怎么定的？<br />很简单，我们还是从第一行说起。007F，实际有效位只有7位，所以，0xxxxxxx就足矣。但是0800开始，有效位至少为8位，我们得增加一个字节，按照UTF-8的规定，2字节的表示方式为110XXXXX 10XXXXXX，我们的编码位为11位(X的个数)，所以，我们最多可以表示UNICODE编码位11位的字符，也就是07FF。07FF过了就是0800，有效位至少为12位，我们得用3字节来表示，按照UTF-8的规定，1110XXXX 10XXXXXX 10XXXXXX，最大编码位为16位，也就是FFFF，最后一行我就不再解释了。<br />通过上面这个过程我们了解了，UNICODE转UTF-8的过程，当然，逆过来就是UTF-8转换成UNICODE。<br />我们通过一个例子来演示上面的过程。汉字&#8220;杨&#8221;，UNICODE的编码位0x6768，二进制形式为0110011101101000，根据上面的图，我们知道它属于第三行，因此，它应该放入1110XXXX 10XXXXXX 10XXXXXX的模板中，结果是11100110&nbsp;10011101&nbsp;10101000，十六进制表示为E69DA8。<br />另外设计编码问题，我们绕不开另一个问题，就是大端小端的问题，不过这个问题，网上资料很多，也很好实践，这里我就不多啰嗦了。<img src ="http://www.cppblog.com/yg2362/aggbug/191746.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/yg2362/" target="_blank">梨树阳光</a> 2012-09-23 22:56 <a href="http://www.cppblog.com/yg2362/archive/2012/09/23/191746.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>共享内存(一)</title><link>http://www.cppblog.com/yg2362/archive/2012/09/06/189732.html</link><dc:creator>梨树阳光</dc:creator><author>梨树阳光</author><pubDate>Thu, 06 Sep 2012 11:26:00 GMT</pubDate><guid>http://www.cppblog.com/yg2362/archive/2012/09/06/189732.html</guid><wfw:comment>http://www.cppblog.com/yg2362/comments/189732.html</wfw:comment><comments>http://www.cppblog.com/yg2362/archive/2012/09/06/189732.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/yg2362/comments/commentRss/189732.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/yg2362/services/trackbacks/189732.html</trackback:ping><description><![CDATA[进程间通信方式包括了管道，消息队列，FIFO，共享内存，而共享内存是其中效率最高的。下图解释了其效率最高的原因(图片截取自《UNIX网络编程》)<br /><img src="http://www.cppblog.com/images/cppblog_com/yg2362/ipc.JPG" width="643" height="502" alt="" /><br />我们可以看到上面的拷贝次数是4次，下面则是2次。<br />接下来我们看看使用，其实网上和书上都有了很多资料，API就是那么几个。<br />int shmget(key_t key,size_t size,int shmflag)。<br />key：可以指定IPC_PRIVATE,那么系统会为你创建一个key，并且返回一个id号。也可以通过ftok函数生成一个key（不了解ftok的童鞋可以动手man一下）。那么为什么要一个IPC既要一个key又有一个ID呢。这里我觉得是为了方便其他进程访问。进程A创建了一个共享内存，内核为其分配一个ID，这个时候进程B想要访问，他怎么获取这个ID(难道需要A把ID发送给B？？)。但是我们用一个key就很方便了。事先A,B进程都知道这个key，那么A创建了，B就可以通过事先知道key找到这块内存。<br />size：共享内存的大小。如果是获得一块内存，则该值应该为0。<br />shmflag:读写权限的组合，可以与IPC_CREAT和IPC_EXCL按位或。当指定一个key时，IPC_CREAT和IPC_EXCL配合使用可以在存在该key的共享内存时返回-1。<br />当该函数调用成功后，返回一个系统分配的共享内存，并且size大小的字节被初始化为0<br /><br /><div>void *shmat(int shmid, const void *shmaddr, int shmflg)<br />有了一块共享内存后，进程需要映射该内存到进程的地址空间。这个函数就是作用。<br />shmid就是之前获得ID，shmaddr如果指定了，就会配合shmflg确定映射地址，不过一般都不这么干的。返回值就是获得的地址，你可以往里面写你或者读你需要的数据了。同时调用了该函数，系统会修改shmid_ds数据。<br /><br />int shmdt(const void *shmaddr)<br />解除绑定关系，参数就是我们之前获取的那个返回地址。(其实我觉得这里参数如果为ID貌似更统一些吧)<br /><br /><div>int shmctl(int shmid, int cmd, struct shmid_ds *buf)</div>这个函数主要做一些修改和查询。比如设置锁，解锁，移除一块共享内存。<br /><br />简单介绍了API，还要说一下一些注意的东西<br />1.共享内存不会把数据写入磁盘文件中，这个区别于mmap<br />2.即使没有进程绑定在共享内存，共享内存也不会消失的。必须通过shmctl或者ipcrm删除(或者更暴力的方式关掉电脑)<br /><br />另外我们可能会考虑，系统最多创建多少个共享内存，一个进程最多可以绑定多少个内存，一个共享内存创建的size最大最小值是多少。其实这些设置在/proc/sys/kernel下面，我们也可以自己写程序来读取。贴一段代码用来获取上面的信息<br /><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #0000FF; ">#define</span>&nbsp;MAX_SHMIDS&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;8196<br /><br /><span style="color: #0000FF; ">int</span>&nbsp;main(<span style="color: #0000FF; ">int</span>&nbsp;argc,<span style="color: #0000FF; ">char</span>&nbsp;*argv[])<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;i,j;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;shmid[MAX_SHMIDS]&nbsp;=&nbsp;{0};<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;*addr[MAX_SHMIDS]&nbsp;=&nbsp;{0};<br />&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">测试可以创建多少个共享内存</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">for</span>&nbsp;(&nbsp;i&nbsp;=&nbsp;0;i&nbsp;&lt;&nbsp;MAX_SHMIDS;++i&nbsp;)<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;shmid[i]&nbsp;=&nbsp;shmget(IPC_PRIVATE,1024,0666|IPC_CREAT);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(&nbsp;shmid[i]&nbsp;==&nbsp;-1&nbsp;)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("create&nbsp;shared&nbsp;memory&nbsp;failed,max&nbsp;create&nbsp;num[%d],%s\r\n",i,strerror(errno));<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">break</span>;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">for</span>&nbsp;(&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;j&nbsp;=&nbsp;0;j&nbsp;&lt;&nbsp;i;++j&nbsp;)<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;shmctl(shmid[j],IPC_RMID,NULL);<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">测试每个进程可以attach的最大数</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">for</span>&nbsp;(&nbsp;i&nbsp;=&nbsp;0;i&nbsp;&lt;&nbsp;MAX_SHMIDS;++i&nbsp;)<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;shmid[i]&nbsp;=&nbsp;shmget(IPC_PRIVATE,1024,0666|IPC_CREAT);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(&nbsp;shmid[i]&nbsp;!=&nbsp;-1&nbsp;)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;addr[i]&nbsp;=&nbsp;shmat(shmid[i],0,0);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(&nbsp;addr[i]&nbsp;==&nbsp;(<span style="color: #0000FF; ">void</span>&nbsp;*)-1&nbsp;)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("process&nbsp;attach&nbsp;shared&nbsp;memory&nbsp;failed,max&nbsp;num[%d],%s\r\n",i,strerror(errno));<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;shmctl(shmid[i],IPC_RMID,NULL);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">break</span>;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">else</span><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("max&nbsp;num&nbsp;of&nbsp;process&nbsp;attach&nbsp;shared&nbsp;memory&nbsp;is[%d]\r\n",i-1);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">break</span>;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">for</span>&nbsp;(&nbsp;j&nbsp;=&nbsp;0;j&nbsp;&lt;&nbsp;i;++j&nbsp;)<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;shmdt(addr[j]);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;shmctl(shmid[j],IPC_RMID,NULL);<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">测试一个共享内存创建最小的size</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;size_t&nbsp;size&nbsp;=&nbsp;0;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">for</span>&nbsp;(&nbsp;;;size++&nbsp;)<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;shmid[0]&nbsp;=&nbsp;shmget(IPC_PRIVATE,size,0666|IPC_CREAT);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(&nbsp;shmid[0]&nbsp;!=&nbsp;-1&nbsp;)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("create&nbsp;shared&nbsp;memory&nbsp;succeed,min&nbsp;size[%d]\r\n",size);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;shmctl(shmid[0],IPC_RMID,NULL);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">break</span>;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">测试共享内存创建最大的size</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">for</span>&nbsp;(&nbsp;size&nbsp;=&nbsp;65536;;size&nbsp;+=&nbsp;1024&nbsp;)<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;shmid[0]&nbsp;=&nbsp;shmget(IPC_PRIVATE,size,0666|IPC_CREAT);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(&nbsp;shmid[0]&nbsp;==&nbsp;-1&nbsp;)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("create&nbsp;shared&nbsp;memory&nbsp;failed,max&nbsp;size[%ld],%s\r\n",size,strerror(errno));<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">break</span>;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;shmctl(shmid[0],IPC_RMID,NULL);<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;exit(0);<br />}</div>好了，下篇开始介绍如何控制读写。</div><img src ="http://www.cppblog.com/yg2362/aggbug/189732.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/yg2362/" target="_blank">梨树阳光</a> 2012-09-06 19:26 <a href="http://www.cppblog.com/yg2362/archive/2012/09/06/189732.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++复习笔记---浅谈拷贝构造函数和赋值构造函数</title><link>http://www.cppblog.com/yg2362/archive/2012/08/31/188919.html</link><dc:creator>梨树阳光</dc:creator><author>梨树阳光</author><pubDate>Fri, 31 Aug 2012 09:13:00 GMT</pubDate><guid>http://www.cppblog.com/yg2362/archive/2012/08/31/188919.html</guid><wfw:comment>http://www.cppblog.com/yg2362/comments/188919.html</wfw:comment><comments>http://www.cppblog.com/yg2362/archive/2012/08/31/188919.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/yg2362/comments/commentRss/188919.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/yg2362/services/trackbacks/188919.html</trackback:ping><description><![CDATA[<p style="margin:0in;font-size:11.0pt"><span style="font-family:Calibri">1.</span><span style="font-family:SimSun">拷贝构造函数的形式</span></p>  <p style="margin:0in;font-size:11.0pt"><span style="font-family:SimSun">对于类</span><span style="font-family:Calibri">X</span><span style="font-family:SimSun">，如果它的函数形式如下</span></p>  <p style="margin: 0in; font-family: Calibri; font-size: 11pt; ">a) X&amp;</p>  <p style="margin: 0in; font-family: Calibri; font-size: 11pt; ">b) const X&amp;</p>  <p style="margin: 0in; font-family: Calibri; font-size: 11pt; ">c) volatile X&amp;</p>  <p style="margin: 0in; font-family: Calibri; font-size: 11pt; ">d) const volatile X&amp;</p>  <p style="margin: 0in; font-size: 11pt; "><span style="font-family: Monaco">且没有其他参数或其他参数都有默认值</span><span style="font-family:Calibri">,</span><span style="font-family:Monaco">那么这个函数是拷贝构造函数</span></p>  <p style="margin:0in;font-size:11.0pt"><span style="font-family:Calibri">X::X(const X&amp;);</span><span style="font-family:SimSun">是拷贝构造函数</span></p>  <p style="margin:0in;font-size:11.0pt"><span style="font-family:Calibri">X::X(const X&amp;,int val = 10);</span><span style="font-family: SimSun">是拷贝构造函数</span></p>  <p style="margin:0in;font-family:Calibri;font-size:11.0pt">&nbsp;</p>  <p style="margin:0in;font-size:11.0pt"><span style="font-family:Calibri">2.</span><span style="font-family:SimSun">一个类中可以存在超过一个拷贝构造函数</span></p>  <p style="margin:0in;font-family:Calibri;font-size:11.0pt">class&nbsp;X&nbsp;{&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</p>  <p style="margin:0in;font-family:Calibri;font-size:11.0pt">public:&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</p>  <p style="margin:0in;font-family:Calibri;font-size:11.0pt">&nbsp;&nbsp;X(const&nbsp;X&amp;);&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</p>  <p style="margin:0in;font-family:Calibri;font-size:11.0pt">&nbsp;&nbsp;X(X&amp;);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#339966">//&nbsp;OK</span>&nbsp;&nbsp;&nbsp;</p>  <p style="margin:0in;font-family:Calibri;font-size:11.0pt">};&nbsp;</p>  <p style="margin:0in;font-size:11.0pt"><span style="font-family:宋体">编译器根据实际情况调用</span><span style="font-family:Calibri">const</span><span style="font-family: 宋体">拷贝构造函数或非</span><span style="font-family:Calibri">const</span><span style="font-family:宋体">的拷贝构造函数</span></p>  <p style="margin:0in;font-family:Calibri;font-size:11.0pt">&nbsp;</p>  <p style="margin:0in;font-size:11.0pt"><span style="font-family:Calibri">3.</span><span style="font-family:宋体">默认的拷贝构造函数行为</span></p>  <p style="margin:0in;font-size:11.0pt"><span style="font-family:Calibri">a)</span><span style="font-family:宋体">先调用父类的拷贝构造函数</span></p>  <p style="margin:0in;font-size:11.0pt"><span style="font-family:Calibri">b)</span><span style="font-family:宋体">如果数据成员为一个类的实例，则调用该类的拷贝构造函数</span></p>  <p style="margin:0in;font-size:11.0pt"><span style="font-family:Calibri">c)</span><span style="font-family:宋体">其他成员按位拷贝</span></p>  <p style="margin:0in;font-family:宋体;font-size:11.0pt">&nbsp;</p>  <p style="margin:0in;font-size:11.0pt"><span style="font-family:Calibri">4.</span><span style="font-family:宋体">默认的赋值构造函数行为</span></p>  <p style="margin:0in;font-size:11.0pt"><span style="font-family:Calibri">a)</span><span style="font-family:宋体">先调用父类的赋值构造函数</span></p>  <p style="margin:0in;font-size:11.0pt"><span style="font-family:Calibri">b)</span><span style="font-family:宋体">如果数据成员为一个类的实例，则调用该类的赋值构造函数</span></p>  <p style="margin:0in;font-size:11.0pt"><span style="font-family:Calibri">&nbsp;c)</span><span style="font-family:宋体">其他成员按位拷贝</span></p>  <p style="margin:0in;font-family:宋体;font-size:11.0pt">&nbsp;</p>  <p style="margin:0in;font-size:11.0pt"><span style="font-family:Calibri">5.</span><span style="font-family:宋体">提供显示的拷贝和赋值构造函数</span></p>  <p style="margin:0in;font-family:SimSun;font-size:11.0pt">基本的原则是子类一定要调用父类的相应函数，参考方式</p>  <p style="margin:0in;font-family:SimSun;font-size:10.0pt">Derive(const Derive&amp; obj):<span style="background:yellow;">Base(obj)</span></p>  <p style="margin:0in;font-family:SimSun;font-size:10.0pt">{</p>  <p style="margin:0in;margin-left:.375in;font-family:Calibri;font-size:10.0pt">&#8230;...</p>  <p style="margin:0in;font-family:SimSun;font-size:10.0pt">}</p>  <p style="margin:0in;font-family:SimSun;font-size:10.0pt">&nbsp;</p>  <p style="margin:0in;font-family:SimSun;font-size:10.0pt">Derive&amp; operator =(const Derive &amp;obj)</p>  <p style="margin:0in;font-family:SimSun;font-size:10.0pt">{</p>  <p style="margin:0in;margin-left:.375in;font-family:SimSun;font-size:10.0pt">if ( this == &amp;obj )</p>  <p style="margin:0in;margin-left:.75in;font-family:SimSun;font-size:10.0pt">return *this;</p>  <p style="margin:0in;font-family:SimSun;font-size:10.0pt">&nbsp;</p>  <p style="margin:0in;margin-left:.375in;font-size:10.0pt"><span style="font-family:Calibri">//</span><span style="font-family:SimSun">方式一</span></p>  <p style="margin:0in;margin-left:.375in;font-family:SimSun;font-size:10.0pt"><span style="background:yellow;">Base::operator =(obj);</span></p>  <p style="margin:0in;margin-left:.375in;font-family:SimSun;font-size:10.0pt">&nbsp;</p>  <p style="margin:0in;margin-left:.375in;font-size:10.0pt"><span style="font-family:Calibri">//</span><span style="font-family:SimSun">方式二</span></p>  <p style="margin:0in;margin-left:.375in;font-size:10.0pt"><span style="font-family:SimSun;background:yellow;">static_cast&lt;Base</span><span style="font-family:Calibri;background:yellow;">&amp;</span><span style="font-family:SimSun;background:yellow;">&gt;(*this) = obj;</span></p>  <p style="margin:0in;margin-left:.375in;font-family:SimSun;font-size:10.0pt">return *this;</p>  <p style="margin:0in;font-family:SimSun;font-size:10.0pt">}<br /><br />另外当你的成员变量有const或者引用，系统无法为你提供默认的拷贝和赋值构造函数，我们必须自己处理这些特殊的情况<br /><br /></p><img src ="http://www.cppblog.com/yg2362/aggbug/188919.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/yg2362/" target="_blank">梨树阳光</a> 2012-08-31 17:13 <a href="http://www.cppblog.com/yg2362/archive/2012/08/31/188919.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++复习笔记---类的函数指针和普通函数指针</title><link>http://www.cppblog.com/yg2362/archive/2012/08/14/187183.html</link><dc:creator>梨树阳光</dc:creator><author>梨树阳光</author><pubDate>Tue, 14 Aug 2012 09:17:00 GMT</pubDate><guid>http://www.cppblog.com/yg2362/archive/2012/08/14/187183.html</guid><wfw:comment>http://www.cppblog.com/yg2362/comments/187183.html</wfw:comment><comments>http://www.cppblog.com/yg2362/archive/2012/08/14/187183.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/yg2362/comments/commentRss/187183.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/yg2362/services/trackbacks/187183.html</trackback:ping><description><![CDATA[我们在类里面会定义成员函数，同时我们也希望定义成员函数指针。因此需要解决3个问题，第一怎么定义类的函数指针，第二赋值，第三使用。<br />
我定义一个类，<br />
<div style="font-size: 13px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: #cccccc; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: #cccccc; padding-right: 5px; padding-bottom: 4px; padding-left: 4px; padding-top: 4px; width: 98%; word-break: break-all; background-color: #eeeeee; "><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #0000FF; ">class</span><span style="color: #000000; ">&nbsp;A<br />
{<br />
</span><span style="color: #0000FF; ">public</span><span style="color: #000000; ">:<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;add(</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">,</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;mul(</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">,</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;div(</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">,</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">);<br />
};<br />
<br />
</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;A::add(</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;a,</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;b)<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">&nbsp;a&nbsp;</span><span style="color: #000000; ">+</span><span style="color: #000000; ">&nbsp;b;<br />
}<br />
<br />
</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;A::mul(</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;a,</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;b)<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">&nbsp;a&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">&nbsp;b;<br />
}<br />
<br />
</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;A::div(</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;a,</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;b)<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">&nbsp;(b&nbsp;</span><span style="color: #000000; ">!=</span><span style="color: #000000; ">0</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">?</span><span style="color: #000000; ">&nbsp;a</span><span style="color: #000000; ">/</span><span style="color: #000000; ">b&nbsp;:&nbsp;a);<br />
}</span></div>
我现在想要定义一个指针，指向A类型中返回值为int，参数为两个int的函数指针。熟悉C的同学马上会写出typedef int (*oper)(int,int)。但是这个用到C++里就有问题了，<br />
因为我们知道，类的非static成员方法实际上还有this指针的参数。比如add方法，它实际的定义可能会这样int add(A* this,int a,int b);因此，我们不能简单把C语言里的那套东西搬过来，我们需要重新定义这种类型的指针。正确做法是加上类型，typedef int (A::*Action)(int,int)<br />
<div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #000000; ">typedef&nbsp;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;(A::</span><span style="color: #000000; ">*</span><span style="color: #000000; ">&nbsp;Action)(</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">,</span><span style="color: #0000ff; ">int</span><span style="color: #000000; ">);<br />
<br />
</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;main()<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;A&nbsp;a;<br />
&nbsp;&nbsp;&nbsp;&nbsp;Action&nbsp;p&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">&amp;</span><span style="color: #000000; ">A::add;<br />
&nbsp;&nbsp;&nbsp;&nbsp;cout&nbsp;</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">&nbsp;(a.</span><span style="color: #000000; ">*</span><span style="color: #000000; ">p)(</span><span style="color: #000000; ">1</span><span style="color: #000000; ">,</span><span style="color: #000000; ">2</span><span style="color: #000000; ">)&nbsp;</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">&nbsp;endl;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">0</span><span style="color: #000000; ">;<br />
}</span></div>
<div><span style="font-size: 13px; "><span style="color: #000000; ">Action&nbsp;p&nbsp;</span><span style="color: #000000; ">=</span>&nbsp;<span style="color: #000000; ">&amp;</span><span style="color: #000000; ">A::add;这个就是赋值语句<br />
调用的时候注意，直接这样(*p)(1,2)是不行的，它必须绑定到一个对象上</span></span><span style="color: #000000; ">(a.</span><span style="color: #000000; ">*</span><span style="color: #000000; ">p)(</span><span style="color: #000000; ">1</span><span style="color: #000000; ">,</span><span style="color: #000000; ">2</span><span style="color: #000000; ">);我们也可以把类的函数指针定义在类的声明里。<br />
<div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #0000FF; ">class</span><span style="color: #000000; ">&nbsp;A<br />
{<br />
</span><span style="color: #0000FF; ">public</span><span style="color: #000000; ">:<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;add(</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">,</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;mul(</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">,</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;div(</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">,</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">);<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;(A::</span><span style="color: #000000; ">*</span><span style="color: #000000; ">oper)(</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">,</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">);<br />
};</span></div>
</span></div>
上面这种方式是针对非static成员函数的，那么static成员函数的函数指针应该怎么定义呢，还能用上面这种方式吗？我们知道static成员函数是没有this指针的，所以不会加上的类的限定，它的函数指针定义方式和C里面的函数指针定义方式一样的。<br />
<div style="font-size: 13px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: #cccccc; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: #cccccc; padding-right: 5px; padding-bottom: 4px; padding-left: 4px; padding-top: 4px; width: 98%; word-break: break-all; background-color: #eeeeee; "><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #0000FF; ">class</span><span style="color: #000000; ">&nbsp;A<br />
{<br />
</span><span style="color: #0000FF; ">public</span><span style="color: #000000; ">:<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;add(</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">,</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;mul(</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">,</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;div(</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">,</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">);<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">static</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;sub(</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">,</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">);<br />
};<br />
<br />
</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;A::sub(</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;a,</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;b)<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">&nbsp;a&nbsp;</span><span style="color: #000000; ">-</span><span style="color: #000000; ">&nbsp;b;<br />
}<br />
<br />
</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;main()<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;(</span><span style="color: #000000; ">*</span><span style="color: #000000; ">pp)(</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">,</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">)&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">&amp;</span><span style="color: #000000; ">A::sub;<br />
&nbsp;&nbsp;&nbsp;&nbsp;cout&nbsp;</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">&nbsp;(</span><span style="color: #000000; ">*</span><span style="color: #000000; ">pp)(</span><span style="color: #000000; ">10</span><span style="color: #000000; ">,</span><span style="color: #000000; ">5</span><span style="color: #000000; ">)&nbsp;</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">&nbsp;endl;<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">0</span><span style="color: #000000; ">;<br />
}</span></div>总结起来，非static成员函数的函数指针需要加上类名，而static的成员函数的函数指针和普通的函数指针一样，没有什么区别。<br />另外注意一点的是<br />如果函数指针定义在类中，调用的时候有点区别。<br /><div style="font-size: 13px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: #cccccc; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: #cccccc; padding-right: 5px; padding-bottom: 4px; padding-left: 4px; padding-top: 4px; width: 98%; word-break: break-all; background-color: #eeeeee; "><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #0000FF; ">class</span><span style="color: #000000; ">&nbsp;A<br />{<br /></span><span style="color: #0000FF; ">public</span><span style="color: #000000; ">:<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;add(</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">,</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">);<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;mul(</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">,</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">);<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;div(</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">,</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">);<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;(A::</span><span style="color: #000000; ">*</span><span style="color: #000000; ">pfunc)(</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">,</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">);<br />};<br /><br /></span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;main()<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;A&nbsp;a;<br />&nbsp;&nbsp;&nbsp;&nbsp;a.pfunc&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">&amp;</span><span style="color: #000000; ">A::add;<br />&nbsp;&nbsp;&nbsp;&nbsp;cout&nbsp;</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">&nbsp;(a.</span><span style="color: #000000; ">*</span><span style="color: #000000; ">(a.pfunc))(</span><span style="color: #000000; ">1</span><span style="color: #000000; ">,</span><span style="color: #000000; ">2</span><span style="color: #000000; ">)&nbsp;</span><span style="color: #000000; ">&lt;&lt;</span><span style="color: #000000; ">&nbsp;endl;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">0</span><span style="color: #000000; ">;<br />}</span></div><img src ="http://www.cppblog.com/yg2362/aggbug/187183.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/yg2362/" target="_blank">梨树阳光</a> 2012-08-14 17:17 <a href="http://www.cppblog.com/yg2362/archive/2012/08/14/187183.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>