【C语言】位运算
编写一个函数getbits,从一个16位的单元中取出某几位(即该几位保留原值,其余位0)。函数调用形式为getbits(value,n1,2)。----简单题目遇到想不到的问题
c语言位运算经典问题:
https://wenku.baidu.com/view/aa4b144410661ed9ad51f3dd.html
位运算屁屁踢:
https://wenku.baidu.com/view/4ed8e1fd1711cc7930b71656.html
近在编写关于C语言位操作的程序,程序的要求如上,具体要求为value为该16位(两个字节)中的数据值,n1为欲取出的起始位,n2为欲取出的结束位,例如:getbits(0101675,5,8) 表示对八进制101675这个数,取出它的从左边起第5位到第8位。
这是相对基础的题目,没有多久编写出了程序,也验证了其结果,是正确的,其中value用unsigned int来定义的,课本上默认unsigned int为16位也就是两个字节,后来意识到我用的操作系统和编译器中unsigned int很可能不是16位的,原因如下:
标准规定,int 的表示范围不能小于 short 的表示范围,long 的表示范围不能小于 int 的表示范围。这就是说 short 型变量占用的空间可能比 int 型变量少,而 long 型变量占用的空间可能比 int 型变量多。16 位(bit)的计算机中,int 和 short 一般都是 16 位,而 long 是 32位;32位的计算机中,short一般是 16 位,而long和int是 32位。TC2(16位的编译器)中,int是16位的;而 Dev-C++(32 位的编译器)中,int 是 32 位的。具体长度的可以由C++编译器的实现厂商自行决定。目前流行的32位C++编译器中,通常int占4字节,short int占2字节。
我自己编写了一个输出语句确认了下,就是printf("%d",sizeof(unsigned int));结果为4,那也就是说我应该用unsigned short int数据类型来定义value变量了,随后就遇到了意想不到的问题了,键盘输入value值,后一直无法正确输出结果来,后来进行排查,定义后赋值value,能够正确运行处结果,看来是输入语句有问题了,后来网上不断的查找解决方案,被这个标题吸引了,
对于短整型scanf函数的奇怪行为(strange behavior of scanf for short int)
网址为:http://www.it1352.com/355925.html,
查看后才发现我用unsigned short int定义了 value值后,输入的时候还是用%d,这样造成了值无法正确输入,需要改成%hd,这个课本中没有提到过,也是遇到这个问题后第一次见的,也算是从错误中不断学习和进步吧。自己编程的程序如下:
#include <stdio.h> typedef unsigned short int ui16; int main() { ui16 getbits_1(ui16 value,ui16 n1,ui16 n2);//方法一 ui16 getbits_2(ui16 value,ui16 n1,ui16 n2);//方法二 ui16 value; ui16 a,b; ui16 result; printf("请输入要处理的整数:\n"); scanf("%ho",&value); printf("请输入起始位和结束位:\n"); scanf("%hd,%hd",&a,&b); printf("截取的数据为:\n"); result=getbits_1(value,a,b); printf("%ho %hd",result,result); return 0; } ui16 getbits_1(ui16 value,ui16 n1,ui16 n2) { ui16 a,b,c; a=value>>(n1); b=~(~0<<(n2-n1+1)); c=a&b; return c; } ui16 getbits_2(ui16 value,ui16 n1,ui16 n2) { ui16 z; z=~0; z=(z<<n1)&(z>>(16-n2-1)); z=value&z; z=z>>(n1); return z; }
#include <stdio.h> void getbits(unsigned short value, int n1, int n2); int main(void) { int value; scanf("%o", &value); printf("Your number is %o, unsigned short is %ld\n", value, sizeof(unsigned short)); getbits(value, 5, 8); return 0; } void getbits(unsigned short value, int n1, int n2) { value = value << n1; value = value >> n1; value = value >> (16-n2); printf("Result = %o\n", value); }