c语言 总结操作符使用 理解二进制存储
2017-12-20 09:49
756 查看
12月19日随笔
12月19日随笔计算机中的补码
求一个数字以二进制存储方式中有多少位数字是1
取数组地址
sizeof
按位取反的妙用
的一个重要特征前者为0则不继续运算当前逻辑与表达式
计算机中的补码
在计算机中如果只用原码来做加法,就会运算错误见下例,因此引入补码机制。1 + (-1) 0000000..0001 //1 1000000..0001 //-1 1000000..0010 //-2 ,计算结果错误
引入补码后
0000000..0001 1111111..1111 0000000..0000 //0 带符号位一起运算,很方便
在c语言中移位运算符默认的是 算术移位 ,即右移补符号位。
再看异或,根据两个性质可以做很多文章,就比如不借助变量交换数,求数组出现一次数个数。
a ^a = 0 a^0 = a
#include <stdio.h> int main(){ int a[5] = {1,3,6,1,6}; int size = sizeof(a)/sizeof(a[0]); int i = 0; int ret = a[0]; for(i=1; i<size; i++){ ret = a[i] ^ ret; printf("%d\n",ret); } printf("%d",ret); }
求一个数字以二进制存储方式中有多少位数字是1
第一种方法是 模2,除2,这种方法对于负数就gg了第二种方法 循环右移(32次),之后按位与1,就可以计数了
第三种方法 见下
int num = -1; int i =0; int count= 0; while(num){ count++; num = num &(num -1); //这个表达式可以总是去掉二进制位里的最后一个1 }
上述代码比第二种方法要高效,因为它不需要知道循环次数,总是从最右边的1开始处理。怎么理解呢,减一是不是把最后一位1变0了,然后再和本身与,就能得到去1的效果.
&取数组地址
printf("%p",arr) //数组首元素地址 printf("%d",arr+1) //数组第二个元素的地址 printf("%p",&arr) //数组的地址!!! printf("%p",&arr +1) //把整个数组的地址跳过了
sizeof
char a; sizeof(a); //1 1个字节 sizeof(&a); //8 打印的是指向char的指针,64位机指针8字节 char c[10] ; sizeof(c); //10 数组名代表整个数组,而不是首元素地址。 sizeof(&c); //8
sizeof 内部表达式不参与运算,因为sizeof在编译的时候就进行处理了。
short int a = 0; sizeof(a = 1 +2 ); printf("%d",a); //0
~按位取反的妙用
求把指定二进制位置数0/1//例,要置第3位为0 000000000101 111111111011 //和这个数字相与,可以保证其他位不变,第三位置0,但是这个数怎么的到呢 000000000100 //由这个数按位取反就可以了,这个数好得到呀,1<<3位就好了
而置第n位为反,只需要和指定序列异或运算就可以了。
&&的一个重要特征,前者为0,则不继续运算当前逻辑与表达式
int i =0 ,a = 0, b = 2,c =3,d =4; i = a++ && ++b && d++; //a = 1 ,b =2,d =4;
同样的||前者为1,则不继续运算当前逻辑或表达式。
练习1.写一个函数返回参数二进制中 1 的个数
#include <stdio.h> int count_one(int key){ int count = 0; while(key){ count ++; key = key&(key - 1); } return count; } int main(){ int key = 0; int ret = -1; scanf("%d",&key); ret = count_one(key); printf("%d",ret); }
2.获取一个数二进制序列中所有的偶数位和奇数位,分别输出二进制序列。
#include <stdio.h> int main(){ int key = 0; int count = 1; int i =0; int que[35]={0}; //这里一定一定要初始化,因为后面不会全部覆盖初值,造成不确定因素 scanf("%d",&am b7e2 p;key); //每次右移一位,取最低位存数组里 while(key){ que[32-count] = key&1; count++; printf("count = %d key&1 =%d\n",count,key&1); //测试 key = key>>1; } printf("\n二进制序列\n"); for(i=0;i<32;i++){ printf("%d ",que[i]); } printf("\n偶数位\n"); for(i=0;i<32;i+=2){ printf("%d ",que[i]); } printf("\n奇数位\n"); for(i=1;i<32;i+=2){ printf("%d ",que[i]); } }
3.输出一个整数的每一位
#include <stdio.h> int main(){ int key = 789; while(key){ printf("%d\n",key%10); //模10除10 key/=10; } }
4.两个int(32位)整数m和n的二进制表达中,有多少个位(bit)不同?
#include <stdio.h> int count_one(int key){ int count = 0; while(key){ count ++; key = key&(key - 1); } return count; } int main(){ int key1 = 1999,key2 =2299; int tmp = key1 ^ key2; //不同的位 置1 int ret = 0; ret = count_one(tmp); //利用前面写过的计算1函数 printf("%d",ret); }
相关文章推荐
- C语言操作符使用总结
- C语言:数据类型、存储区字节数、占位符、sizeof、输入输出、二进制相关、操作符(++,--)、主函数参数
- JNI 使用总结 (JAVA 调用C语言编写的DLL/SO/SL文件)
- hibernate mysql 存储二进制文件问题总结
- 存储过程里output的使用总结
- 存储过程里output的使用总结
- mysql存储过程学习总结-操作符
- c语言中不使用操作符实现两个数相加
- C语言中“:”的使用方法的总结
- 自己关于指针在函数中使用的理解和总结
- 在不使用*、/、+、-、%操作符的情况下,如何求一个数的1/3?(更新了一些解释,用C语言实)
- 索引、视图、游标、存储过程和触发器理解总结
- 从内存理解c语言中变量的存储类型
- 俺使用的C语言面向对象范式(第四节:多态的实现 与 总结)
- A*启发搜索+二进制压缩存储; 代码效率不错,对二进制的应用理解越来越深刻了;
- 上传图像并使用ASP.NET 2.0数据源控件代码存储二进制数据
- 关于sizeof操作符的理解和总结
- 常用 SQL 语句总结 (主要是存储过程中的使用)
- C语言中地址操作符&的使用
- mysql存储过程学习总结-操作符