loop_in_codes

低调做技术__欢迎移步我的独立博客 codemaro.com 微博 kevinlynx

共6页: 1 2 3 4 5 6 
用windows live客户端发。。。或者先在其他地方写好,发的时候粘贴过来
re: 学生时代做的东西-留个纪念 Kevin Lynx 2011-02-26 14:57
@favormm
no, i'm not.
我觉得就为了归纳一些共同接口,这样子做有点过了。不妨考虑在类设计时就将功能分出来。与其想尽办法保持类接口的数量不膨胀,倒不如让类的功能单一。简单的继承结构就够了。
re: 写程序真他妈爽啊 Kevin Lynx 2011-02-25 09:05
纯表
re: 绿色免费记单词软件-语言岛 Kevin Lynx 2011-02-23 13:08
ubuntu10.04无法运行
re: Lisp的本质(The Nature of Lisp)(转) Kevin Lynx 2011-02-16 09:44
坚持看完了,感觉讲到DSL的时候就嘎然而止了。总的来说作者写的不错。让我也想去学学lisp
re: 初学java(一) Kevin Lynx 2011-01-24 10:00
@あ维wêiセ
cppblog首页推荐内容需要博客作者对内容自我斟酌 :)
@战魂小筑
:) 金点工作室。。。
LS两位都算是这行的元老了。
re: 代码自动生成-宏递归思想 Kevin Lynx 2011-01-13 09:10
@溪流
从原理上来看的话,我们最终需要的是各种带有1、2、3之类的相似符号,例如 typename P1,typename P2,....,所以,逐步拆分这些符号后,就会自然而然地得到”基础数字序列生成器”:DEC。

相当于,DEC系列宏就是这个宏库的基础,而PARAM_1则算是稍微上层一点的应用。

ps,很久没捣鼓这些复杂的东西,诸多遗忘,见谅。
同感。经常看到领导说某某交流有问题,但是这个某某恰好是埋头做事情的人。比只说不做的人好多了。
恩。果然是20-30块钱一页。。。
- -| 我也收到这个留言了。。。不过讨论的还没LZ细。
EasyEdit :D
re: 恶心的转载 Kevin Lynx 2010-12-24 09:00
话说整理书上的内容,算不上多大的原创吧?包括这个“让CPU占用率XX”我以前同事也写过类似的。。。http://www.cppblog.com/Fox/archive/2008/04/17/control_cpu_using_curve.html

我的BLOG也四处被转载,但是并不打算去追究,别人用不商用,就当传播知识。
re: [译文]VIM使用者大脑的形态 Kevin Lynx 2010-12-23 09:14
手不离开主键盘的感觉很好。
re: 软件开源很重要吗? Kevin Lynx 2010-09-21 15:34
贡献你的知识影响别人也算是对于自己曾经在网络上获取免费知识的一种回报。但是,开与不开全看个人,骂人的就不对了。
基本上不会有人在游戏逻辑线程里放置IO操作的代码吧,包括网络和DB。对于玩家的重要操作有时候需要立即存储。
re: 剑3资源格式分析(一) Kevin Lynx 2010-07-16 13:45
@johndragon
这种东西。最好声明一下,“本文仅用作学习” - -
re: 游戏资源包简单设计 Kevin Lynx 2010-07-09 09:26
@大虾
把文件内容直接替换了,然后修改file_tag
re: 关于C++之“复杂” Kevin Lynx 2010-07-07 13:45
此帖必火。最后很可能成为又一轮语言大战。
我以前是C++/OO的狂热者,后来有变得不狂热。其他语言我熟的不多,就拿C做比较。
1、语法相对复杂,语法规则细节太多,越是懂得语法细节越多,写出的代码越是往复杂方向靠。记得我以前写过一篇牢骚贴(强大的BCB),那个移植我的C++代码到BCB编译器时所经历的编译除错,就整出了很多语法细节。尤其是参杂了模板的C++。我想,就我以前在C++上的努力而言,不算不懂乱说的人吧
2、带来的设计复杂,基本上C++会被捆绑到OO上,见到的C++库越多,了解的设计思想越多,自己做的设计也越来越倾向于复杂,我们的代码是否真的会面临这些变化?相比而言,在用C写库代码时,就非常直接,接口设计方式也很简单。
@zuhd
老实说是二流本科的不才女。。。
re: 多线程还是单线程? Kevin Lynx 2010-07-06 11:58
@tanxw
AI单独到一个进程里,这些逻辑模块之间又涉及到线程同步问题了。
@浩毛
对于只有游戏逻辑和网络IO的进程而言,你说的只开一个线程,似乎也在理。不过由于网络IO这块情况可能比理论上要复杂很多,例如实际使用的网络IO机制(IOCP)、网络层数据的拷贝、封包组建等,似乎保险的做法还是开多个线程来做。何况,逻辑线程可能还会涉及到限帧问题。拿去运营的服务器一般也是多核的。LINUX下线程实现的效率如果真的太那个啥,或者可以考虑多进程的结构(网络模块和逻辑模块位于不同进程)。
@陈梓瀚(vczh)
看到MS字母组合,我们果断自卑了。。。- -|
@ccsdu2009
没多大要求,盖老板给个稀饭钱就知足了 :D
- -| 这个要不要顶呢。。
re: 网游中的玩家移动 Kevin Lynx 2010-06-23 09:39
@keror
这里返回的消息,客户端仅用于递减请求计数。不会立即影响客户端的移动效果。
- -!
路过,你懂的
re: 网游中的玩家移动 Kevin Lynx 2010-06-23 08:52
@evoup
话说你没有看清楚我说的内容。每一步发的消息仅用于服务器的验证,不同步客户端数据。
@小时候可靓了
这个属于另一个话题了,客户端会粗略估算其他角色的移动情况,如取得方向模拟其行走,以达到自然的效果,改天细谈下。
re: 游戏资源包简单设计 Kevin Lynx 2010-06-21 11:36
@饭中淹
对啊,好方法。移动分配表的代价比移动文件内容小多了。不错。
re: 求解:编译顺序问题 Kevin Lynx 2010-06-12 09:02
个人觉得这种情况,就设计感觉上来说就不好。互相耦合。单就这个情况来看,可以把类型抽离到一个公共文件里。如果是对类本身的依赖,当然可以使用前置声明。
这个应该是在处理类定义之前,发现了同名的宏,导致在编译之前(预处理阶段)把类成员当作宏做了宏体的替换。LZ说法欠妥:)
这个标题。我感觉LZ在说自己。- -!
re: 令人气愤的现象 Kevin Lynx 2010-05-28 08:45
表示,这种人太多,无视了。
我觉得完全可以忽略子对象(成员变量对象)的细节,也就是说假设这里的内存池只管理player,那么你就没必要去理会这些容器底层的细节。因为这会成为一个递归的情况。
如果仅仅是为了缓存player本身,最好还是在将player放回池中的时候,来次reset吧。不然下一次再取出来的时候,会得到一个并非处于initial状态的对象,这会增加逻辑的负担。
汗。。- - 。。偶然间看到LZ 博客HGE一栏居然转载有我N久以前乱写的东西,真巧啊。。
唉,淡定吧。这种情况让我头疼。
@小时候可靓了
刚想补上这句,差距都是12.。。- -
我这边差距都是4,正常差距,但是顺序诡异。。。
@小时候可靓了
0x0012ff60 a
0x0012ff54 p
0x0012ff48 i ???
如果是这样的话,那这个才是正确的排列地址啊。诡异的是我那个情况。
@小时候可靓了
饭给的解释是我在群里跟他谈过的。
这个解释是我在看汇编的时候看到的:
00401750 push ebp
00401751 mov ebp,esp
00401753 sub esp,0Ch
00401756 lea eax,[ebp+4]
00401759 mov dword ptr [p],eax

恰好a莫名其妙地出现在栈顶,而不是p,(而在我举的包含i的例子中,作为出现在最后定义的i却莫名其妙地出现在栈顶),加上这个push ebp,就出现了3。

谁能给个解释:为什么a、p、i三者的相对地址和其定义顺序存在差别?(难道编译器对数组的处理要特殊点?)
@小时候可靓了
这个不需要你重申,我更不希望我来重申我的问题:
解释下这个:
int a[1];
int *p;
int i;

a : 0x0012ff74
&p:0x0012ff78
&i:0x0012ff70

注意p在中间 。
@坏
需要适当调整 3 这个偏移量

ps,当然也取决于编译器生成的指令。鉴于目前我也不明白为什么偏移是3,看起来LZ也无法给出详细的说明,这个3很有可能只是个巧合。

1、除了push ebp外可能还有压入其他寄存器的值(保存寄存器信息)
2、a理论上应该不在栈顶,就像我例子中的i,而p应该在栈顶
@小时候可靓了
{
int a;
int b;
int c;
}
按我的理解,c应该在栈顶,而不是a。但是实际上跟踪你的代码来看,a确实在栈顶,在p后添加变量int i ,又有意外:
a : 0x0012ff74
&p:0x0012ff78
&i:0x0012ff70
@小时候可靓了
a 的地址是 ebp -8
p 的地址是 ebp-4

这两个结论从何而来?何况,为什么要+3?

ps,话说这样N多回复会给你BLOG增加不少积分啊 :D
@小时候可靓了
我说的是有点问题。跟参数没关系。参数先于返回地址压栈。- - 昏头了。

话说回来,仔细分析的话,我突然发觉:
int* p = (int*)&a[0]+3;
这里为什么会是3呢?跟了下汇编,发觉直接被翻译为ebp+4了:
push ebp
mov ebp, esp
...
mov eax, [ebp+4]

不是很明白这个地方。

饭老大说得和我一样。
这个可以从call和ret指令所做的事情来看,更涉及到函数调用在编译器以及目标机器指令问题。不过因为这里不存在虚拟机问题,都是x86,也就只针对call和ret而言:

不难想象在main之前的地方有如下代码:
; 压参数
push xxx
push xxx
push xxx
call main

;main
xxx
xxx
ret

首先call的动作主要包括:先压入返回地址到堆栈上(ebp指向),而c函数中,函数负责堆栈平衡,那么main中清除局部变量,改变ebp后,可以肯定ebp指向的当前堆栈中的值就是返回地址。ret指令则是从栈顶取出该地址并执行PC寄存器的跳转。

另一方面,函数调用时的运行时堆栈问题:首先栈是向下增长的,函数A调用函数B,那么首先压入参数到栈中,在函数B中因为局部变量的增长栈继续向下增长,也就是说,最终可以通过ebp的偏移取得函数A中局部变量的信息。他们贡献同一个栈:
--stack--
A:local_var1
A:local_var2
A:ret_addr
B:arg_var1
B:arg_var2
B:local_var1
....
基于以上两个条件,指针a[0]+3,则向高地址偏移了12字节的地址(3*sizeof(int)),看下main函数的参数,实际上是3个:argc, argv, env。这样偏移后,恰好就是调用main那个函数在使用call时,压入的返回地址。

因此,在main返回时,ret弹出的地址已经被改变。

ps:
在错误地跳转到test后,test执行完去ret时,堆栈上提供的返回地址是不定的,崩溃也很正常了。
其实没必要考虑到这么复杂,关键在于要认清指针在这里表现出来的语法特性:
指针同普通变量一样,在函数内部的指针定义就是一个简单的局部变量:
main()
{
int *p ; // 可以简单理解为一个类型为int*的变量
}
C语言里的函数调用按值传递,所以:
void func( int *p );
func( p ); // 把变量p的值复制过去,跟p本身没有关系

void func( int *p )
{
}

函数参数依然被存储于函数局部栈里,何况,这里的实参p,按照我这里说的语法规则,只不过是main里p的拷贝,这就如同:
main()
{
int p ; // p是一个int类型的变量
func( p ); // 复制p的值给func的实参
}

func( int p )
{
}

当然,一睹汇编代码,也确实能认清真相。不过我觉得,既要从本质去看,也要从规则去看。这里的规则我主要指的是语言带给我们的整体语法感觉。恩,这个说不清了。
re: 某内存池中的指针用法 Kevin Lynx 2010-05-04 17:44
就是把一整块内存分成多块,利用未使用位置串联下这些块。很多代码都会涉及到这种用法。
re: gc库概念简化版 Kevin Lynx 2010-04-30 10:23
每一次调用gc_collect的时候,s_color变为对立值(0->1, 1->0),然后gc_mark_r将位于s_links中的指针全部标记为当前的s_color值,那么在gc_collect之前gc_unlink的指针依然为原来的s_color,即未被标记,然后gc_collect回收这些未被标记的指针(指向的内存)。

不是很明白,s_linkClean在这里的作用。
re: gc库概念简化版 Kevin Lynx 2010-04-30 09:42
- - 果然需要自己“改改才能编译过去”。。
共6页: 1 2 3 4 5 6