手工实现字节对齐 及 代码质量思考
2009-03-26 12:16
253 查看
在游戏编程中,我们经常听到序列化这个词汇。在一些网络通讯和数据处理时,我们便会用到序列化。这里先不具体说明序列化。这里只说序列化过程中可能用到的字节对齐的问题:
我们首先是定义了这样一个宏:
#define ALIGN( __size, __bits ) ( ( ( ( __size - 1 ) >> __bits ) + 1 ) << __bits )
我们在使用的时候:
DWORD dwSize = ALIGN( dataSize, 2 );
这样传入一个2,表示4字节对齐. 假如我的dataSize = 10; 通过这个宏我们可以算出dwSize = 12;
这种方法相对来说用得比较巧妙,当然可能还有其他更好的方法, 我们这里不追究. 这里主要想说说我自己的一些感悟而已.
最初的想法我可能会把这个宏给写成这样:
#define ALIGN( __size, __bits ) ( ( __size % __bits == 0 ) ? __size : ( ( ( __size / __bits ) + 1 ) * __bits ) )
这样虽然实现了功能, 但是总体来说还是麻烦了.. 不说追求完美. 至少应该在准备着手写的时候多想一下还有没有其他更简单高效的办法.
之前也碰到过一些东西, 比如你在一个函数中调用另外一个函数. 另外一个函数是事先别人已经写好的. 你恰好又要在被调函数里获取你主调函数里面计算出来的一个值. 这时你可能第一个想法就是给函数加一个参数. 为了跟其他地方兼容就加一个默参. 这样当然是好的..但是有的时候你可能并不这么想. 你可能会去把这个计算的值给添加成被调函数的所在类的成员里面去. 这样一个临时用来做判断的值, 你就无形之间增加了类的负担. 特别是在服务器的严谨逻辑下, 都这样写的话将造成很多浪费..
再举一个例子吧, 假如我们有一个玩家组队的队伍数组. 里面都是玩家对象. 我们一个玩家退出了队伍. 我们就得删除这个玩家在数组中的数据. 这时我们会怎么做呢?
我们是不是要遍历到玩家的索引,然后删除,然后把后面的玩家依次往前移动一个单位呢? 对,想法是对的,落实的话我们可以考虑一下了. 到底要循环多少次? 需不需要循环?
我们便可以找到答案:
先遍历找到玩家的索引,比如用index表示, 玩家数组用playerArray, 之后我们就可以这样:
if ( index < MAX_TEAM_PLAYER - 1 )
{
memcpy( playerArray[ index ], playerArray[ index + 1 ], sizeof( playerArray[ index + 1 ] ) * ( MAX_TEAM_PLAYER - index - 1 ) ) ;
}
memset( playerArray[ MAX_TEAM_PLAYER - 1 ], 0, sizeof( playerArray[ MAX_TEAM_PLAYER - 1 ] ); // 这句不能忘哟 - -
这样是不是就简单些了? 当然这里只是举的简单的例子..更多的还是需要我们去体会..这里只是提出思考..有什么地方说的不对望指教..
我们首先是定义了这样一个宏:
#define ALIGN( __size, __bits ) ( ( ( ( __size - 1 ) >> __bits ) + 1 ) << __bits )
我们在使用的时候:
DWORD dwSize = ALIGN( dataSize, 2 );
这样传入一个2,表示4字节对齐. 假如我的dataSize = 10; 通过这个宏我们可以算出dwSize = 12;
这种方法相对来说用得比较巧妙,当然可能还有其他更好的方法, 我们这里不追究. 这里主要想说说我自己的一些感悟而已.
最初的想法我可能会把这个宏给写成这样:
#define ALIGN( __size, __bits ) ( ( __size % __bits == 0 ) ? __size : ( ( ( __size / __bits ) + 1 ) * __bits ) )
这样虽然实现了功能, 但是总体来说还是麻烦了.. 不说追求完美. 至少应该在准备着手写的时候多想一下还有没有其他更简单高效的办法.
之前也碰到过一些东西, 比如你在一个函数中调用另外一个函数. 另外一个函数是事先别人已经写好的. 你恰好又要在被调函数里获取你主调函数里面计算出来的一个值. 这时你可能第一个想法就是给函数加一个参数. 为了跟其他地方兼容就加一个默参. 这样当然是好的..但是有的时候你可能并不这么想. 你可能会去把这个计算的值给添加成被调函数的所在类的成员里面去. 这样一个临时用来做判断的值, 你就无形之间增加了类的负担. 特别是在服务器的严谨逻辑下, 都这样写的话将造成很多浪费..
再举一个例子吧, 假如我们有一个玩家组队的队伍数组. 里面都是玩家对象. 我们一个玩家退出了队伍. 我们就得删除这个玩家在数组中的数据. 这时我们会怎么做呢?
我们是不是要遍历到玩家的索引,然后删除,然后把后面的玩家依次往前移动一个单位呢? 对,想法是对的,落实的话我们可以考虑一下了. 到底要循环多少次? 需不需要循环?
我们便可以找到答案:
先遍历找到玩家的索引,比如用index表示, 玩家数组用playerArray, 之后我们就可以这样:
if ( index < MAX_TEAM_PLAYER - 1 )
{
memcpy( playerArray[ index ], playerArray[ index + 1 ], sizeof( playerArray[ index + 1 ] ) * ( MAX_TEAM_PLAYER - index - 1 ) ) ;
}
memset( playerArray[ MAX_TEAM_PLAYER - 1 ], 0, sizeof( playerArray[ MAX_TEAM_PLAYER - 1 ] ); // 这句不能忘哟 - -
这样是不是就简单些了? 当然这里只是举的简单的例子..更多的还是需要我们去体会..这里只是提出思考..有什么地方说的不对望指教..
相关文章推荐
- 手工实现字节对齐 及 代码质量思考
- 手工实现字节对齐 及 代码质量思考
- 内存字节对齐---代码实现(自己整理的,这是一切字节对齐最本质的东西)
- 用代码实现手工“点击按钮”操作
- 持续集成之②:整合jenkins与代码质量管理平台Sonar并实现构建失败邮件通知
- 基于纯Java代码的Spring容器和Web容器零配置的思考和实现(3) - 使用配置
- 基于纯Java代码的Spring容器和Web容器零配置的思考和实现(1) - 数据源与事务管理
- 基于纯Java代码的Spring容器和Web容器零配置的思考和实现(3) - 使用配置
- 测试内存字节对齐代码
- 用 487 字节的 C 代码实现 2048 游戏
- vbs:一段比较精简的代码实现取得字符串的"字节"数
- Struts2:输入 da24 校验-采用手工编写代码实现
- 如何实现128字节对齐的数据结构
- 字节对齐 代码验证
- 用代码实现文字扩散对齐
- iOS中UILabel text两边对齐的实现代码
- css span右对齐 css li标签中span日期靠右布局实现代码
- 关于卷积神经网络原理以及代码实现应用的几点思考
- 堆排序的代码实现与思考
- 集成开源系统实现自动化构建、代码质量评估、项目信息统计