编程之美1.2中国象棋将帅问题——转载+自己的一点理解

分享这个链接:http://book.douban.com/annotation/13753057/


 
  
  
这是个关于如何利用位运算解决问题的一个简单的运用,可以看到位运算合理地利用一个变量解决象棋将帅问题。
算法本身很简单,重点是位运算的应用。<BOP>上还有两个更简洁的算法:第一个:
  
  
  1. #include<stdio.h>
  2. #define BYTE unsigned char
  3. int main(void)
  4. {
  5. BYTE i = 81;
  6. while(i--)
  7. {
  8. if((i / 9) % 3 == (i % 9) % 3)
  9. continue;
  10. printf("A = %d, B = %d\n", i /9 + 1, i%9 + 1);
  11. }
  12. return 0;
  13. }
可以把变量i想象成一个两位九进制的变量,而i在计算机中存储的值是i的十进制表示。
则i/9的计算机处理结果,即结果直接去掉小数点后部分的结果即是此九进制数的第二位,
而i%9即是此九进制数的个位。本程序用此九进制数的第二位保存A的位置,个位表示B的位置。
最大值为88,即为十进制的80.程序从十进制的80,即九进制的88遍历到十进制的0,即九进制的0.
将符合条件的位置全部输出。第二个:
  
  
  1. #include<stdio.h>
  2. int main(void)
  3. {
  4. struct
  5. {
  6. unsigned char a:4;
  7. unsigned char b:4;
  8. }i;
  9. for(i.a = 1; i.a <= 9; i.a++)
  10. for(i.b = 1; i.b <= 9; i.b++)
  11. if(i.a % 3 != i.b % 3)
  12. printf("A = %d, B = %d\n", i.a, i.b);
  13. return 0;
  14. }
算法与上面的如出一辙。其中unsigned char a:4表示结构体中a的位域只有4位,高位用作它用。只能在结构体里使
用,建议尽量少用,会破坏程序的移植性。当结构体中的元素的取值范围很小时,可以将几个字段按位合成一个字段
来表示,起到节省内存空间的作用。

Ex:
  
  
  1. #include<stdio.h>
  2. int main(void)
  3. {
  4. struct test
  5. {
  6. unsigned char a:4;
  7. unsigned char b:4;
  8. }i;
  9. i.a = 15;
  10. i.b = 10;
  11. printf("%d\n", sizeof(i));
  12. }
将上面例子中的变量i的大小输出,结果为1字节。说明i.a和i.b各占4位。结构体是C语言中的一种常用的自定义数据
结构。看下面的例子:
  
  
  1. #include<stdio.h>
  2. int main(void)
  3. {
  4. struct test
  5. {
  6. int a;
  7. char b;
  8. }i;
  9. printf("%d\n",sizeof(i));
  10. }
按理说结构体变量i的大小应该是sizeof(int)+sizeof(char),即5,而输出显示的结果为8。再看一个例子:
  
  
  1. #include<stdio.h>
  2. int main(void)
  3. {
  4. struct test
  5. {
  6. int a;
  7. char b,c;
  8. }i;
  9. printf("%d\n",sizeof(i));
  10. }
应该是6对吧?结果还是8.这是为什么呢?这是因为在32位的操作系统上,操作系统组织数据是以32位(4个字节),
因此各种变量的size都一般都是4的倍数。而且结构体数据都是按照定义时所使用的顺序存放的,因此在第一个例子
中尽管b变量只会占有一个字节,但是a + b = 5 > 4,因此第一个4个字节存放a,第二个4个字节用于存放b,这样实
际上就浪费了3个字节。在第二个例子中第二个4个字节用来存放b和c。所以,在结构体中要注意结构体中的变量定义
的顺序,不同的顺序可能会造成占用空间的不同。这在嵌入式程序设计等系统资源比较少的情况下尤为重要。比如如
下两种结构体:
  
  
  1. #include<stdio.h>
  2. struct m
  3. {
  4. char a;
  5. int b;
  6. char c;
  7. }x;
  8. struct n
  9. {
  10. char a;
  11. char c;
  12. int b;
  13. }y;
  14. int main(void)
  15. {
  16. printf("m:%d\nn:%d\n", sizeof(x), sizeof(y));
  17. return 0;
  18. }
对于结构体m来说,x变量的大小为12,而y变量的大小为8.编译器是按程序员在结构体中声明变量的顺序处理的。不
当的顺序会造成空间的浪费。读者可以想到发生这样情况的原因的。所以建议声明结构体时,按照不同变量的类型,
按占用空间的大小升序或降序声明会取得较好的空间占用。
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值