20135202闫佳歆-第二章家庭作业-2.69
2015-10-20 16:11
281 查看
第二章家庭作业
选题:2.69
分值:三分
作业过程:
以下是rotate_right函数的代码:unsigned rotate_right(unsigned x, int n) { int endbit; int i; if(n==0) return x; else { for(i=0;i<n;i++) { endbit = x & 0x1; endbit = endbit << (8*sizeof(unsigned)-1); x = x >> 1; x = x | endbit; } } return x; }
这里用到的原理是,区分n的情况,如果是0则直接返回原值,如果不是0,就按照移位的次数控制循环,每次循环只移位1位。
具体循环的实现,是借助了一个变量为endbit,最后一位,用来保留右移一位后损失掉的那位,再通过移位使这位变成最高位,最后与x移位后的数据进行或运算,这样就完成了循环右移一次的功能;共需循环右移几次,就重复几次这个循环。
完成的代码如下:
#include <stdio.h>
unsigned rotate_right(unsigned x, int n);
int main()
{
int n = 0;
unsigned x;
int w = sizeof(unsigned)*8;
int flag = 0;
unsigned result;
while(!flag)
{
printf("please input how many bits you want to rotate_right shift:\n");
scanf("%d",&n);
if (n < 0 || n >= w)
{
printf("Wrong! Please input again!\n");
}
else
flag = 1;
}
printf("please input your data:\n0x");
scanf("%x",&x);
result = rotate_right(x,n);
printf("the result is:0x%x\n",result);
return 0;
}
unsigned rotate_right(unsigned x, int n) { int endbit; int i; if(n==0) return x; else { for(i=0;i<n;i++) { endbit = x & 0x1; endbit = endbit << (8*sizeof(unsigned)-1); x = x >> 1; x = x | endbit; } } return x; }
实验运行结果如下:
实验中遇到的问题:
这个函数原型的构造并不难,找到思路后困扰我一时的只是是用或还是与,这个很容易就能够解决,更大的问题在我的主函数中输入无论如何都得不到正确的结果,后来发现是因为我的输入是0x12345678,我以为这个可以直接转换为16进制但是不可以,输出也是十进制,所以这导致了我的结果错误百出,后来我通过百度发现了%x的方法,输入输出格式改为这个之后就可以方便的输入输出16进制,并且在输入之前加了提示语0x,就可以得出正确的结果了。这道题本身难度不算大,我主要还是栽在了自己的粗心上,没有注意输入输出格式,只想当然的去做,吸取了这次教训,以后的作业就不会有那么多冤枉路了。
代码的优化
从每次右移一位,按循环次数控制右移位数,能不能扩展成一步到位移动n位呢?我把代码变成了以下样子:unsigned rotate_right(unsigned x, int n) { int endbit; int i; if(n==0) return x; else { endbit = x << (8*sizeof(unsigned)-n); x = x >> n; x = x | endbit; } return x; }
这样就可以直接移动n位了。
这里还有一个小插曲,关于开始的左移位数是要-n还是-什么,是右移了n位,上面的左移就要减n。
然后我又想,n=0的情况能不能并进去?代码就变成了这样子:
unsigned rotate_right(unsigned x, int n) { int endbit; endbit = x << (8*sizeof(unsigned)-n); x = x >> n; x = x | endbit; return x; }
验证是可以的。
endbit作为一个中间值,是不是有点多余?去掉之后变成:
unsigned rotate_right(unsigned x, int n) { x = (x >> n) | x << (8*sizeof(unsigned)-n); return x; }
也是可以的,更简洁了。
那么可以干脆直接用return返回:
unsigned rotate_right(unsigned x, int n) { return (x >> n) | x << (8*sizeof(unsigned)-n); }
这个一步步简化代码的过程让我做完了之后十分满意,最开始的想法很简单,但是代码实现却很复杂,通过一步步的简化最终使代码变的简洁好看,成就感很大。但是对于我现在的水平,如果直接给我这样的一个代码,阅读起来还是有些费劲的,需要多加练习。
相关文章推荐
- 使用javascript取得网站的根路径
- JqGrid单选
- Protege A DOT error has occurred错误
- C语言实现大整数乘法代码的完整代码及运行结果
- 传域名服务商“新网”恶意调价:降代理级别强制消费
- mysql事务
- [前端] jquery获取append追加的input值
- 爱在心中
- 图片下面加字排版
- MFC单文档视图之图标资源加载及绘制
- 交叉熵代价函数
- Hbase-1.1.2 Java API 操作
- openstack Nova、Cinder、Neutron资源配额设置
- 关键词研究
- [Java]剑走偏锋的10条编程技巧
- jQuery中的.bind()、.live()和.delegate()之间区别分析
- WebSocket实例—初级聊天室(来自Tomcat8的examples)
- MegaRAID阵列卡配置RAID阵列 - WebBIOS - CLI
- Ubuntu14.04给桌面上添加计算机图标
- MongoDB Replica Sets + Sharding 方案 及 chunks块 和 片键分析