企业网站 费用网站开发人才需求
操作符详解


 
正数的原码反码补码相同
负数的原码最高位数是1,正数为0
整数在内存中存储的是补码

负数的左移与右移,移的是补码,打印的是源码
补码-1取反就是原码。
左移有乘2的效果

左移和右移只针对整数。
vs里的右移操作赋采用的是算数右移,右边丢弃、左边补原符号位
符号位是根据正数还是负数来确定的,正数补0,负数补1.


总结:
计算的是以补码形式计算,打印的是以原码形式存在。


计算的时候要用补码,因为整数在内存中存储的是补码。
按位与二个同时为1就得1,有一个不得1就为0.

取反的时候不要动符号位。
异或是相同为0,相异为1



0异或a是a a异或a是0
异或支持交换律

统计二进制中有多少个1

任何一个数a按位与1如果==1就说明a的二进制最低位是1
a&1==0 说明a的二进制最低位是0

就比如这段二进制代码 a&1 第1位是0 就&1 得0 就跳过最低位,看第二位,如果第二位&1等于1就让COUNT++,一直循环下去。这样就可以知道这段二进制代码有多少个1了。
方法1 利用&和>>操作符计算出二进制代码有多少个1.

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{int i = 0;int a = 0;while (~scanf("%d", &a)){int count = 0;for (i = 0; i < 32; i++){if ((a >> i) & 1 == 1){count++;}}printf("%d\n", count);}	return 0;
}  

总结
 把一个二进制向右移动i个位移到最低位和1进行按位与进行比,如果==1就说明二进制有1 
从右往左看,每次移到的位位数再增加,最高是32位
方法2:利用/2 %2的方法来

、

想得到二进制的每一位 /2 %2来解决这个问题

//考虑正负数问题
int count_one_bit(unsigned int n)
{int count = 0;while (n){if ((n % 2) == 1){count++;}n /= 2;}return count;
}
int main()
{int n = 0;scanf("%d", &n);int ret=count_one_bit(n);printf("%d\n", ret);return 0;
} 
方法3
利用n=n&(n-1)来达到把n的二进制最右边的1去掉
比如n=-1
1111 n
1110 n-1
1110 n
1101 n-1
1100 n
1011 n-1
1000 n
0111 n-1
0000 n
利用这种效果来实现二进制代码有多少个1

//判断一个数是否是2的次方数

//判断一个数的是否是2的次方数
//n=n&(n-1)
// 0001
//0010
//0100
//1000
int main()
{int n = 0;scanf("%d", &n);if ((n & (n - 1)) == 0){printf("YES\n");}else{printf("NO\n");}return 0;
} 
 
练习2 二进制位 置0或者置 1
编写代码将13⼆进制序列的第5位修改为1,然后再改回0?


//编写代码将13⼆进制序列的第5位修改为1,然后再改回0 ?
// 0001 1101
int main()
{int n = 0;scanf("%d", &n);	// 13  0000 1101 //移到n = n | (1 << 4);  // 0000 1101 | 0001 0000==0001 1101printf("%d\n", n);//复原
//   0001 1101 变成 0000 1101
//   按位与1110 1111 即可   怎么变呢  1的二进制是  0000 0001 左移4位 0001 0000然后取反 1110 1111n = n & ~(1 << 4);printf("%d\n", n);return 0;
} 
 
获取一个整数二进制序列中所有的偶数位和奇数位,分别打印出二进制序列

总结方法:
输入的数只要往右移,把每一个数移到最低位按位与上一个1就可以获得最低的是否是1了,可以明确判断出你输入的数转换成二进制形式有多少个1.
编程实现:两个int(32位)整数m和n的二进制表达中,有多少个位(bit)不同




语法说说支持连续赋值,建议写代码不要这么写。




效果一样。
强制类型转换。



1是40 2是4/8,3是10,4是4/8


逻辑与,左边为假右边就不计算了。
逻辑或,左边为真,右边就不计算了
 
逗号表达式是从左到右计算,整个表达式的结果是最后一个表达式的结果。


 



整型提升


 


一个char类型的占1个bit 相对于8个biye位,他要整型提升是因为    难以直接实现两个8比特字节直接相加运算(虽然机器指令
 中可能有这种字节相加指令)。所以,表达式中各种长度可能小于int长度的整型值,都必须先转
 换为int或unsigned int,然后才能送入CPU去执行运算。
例如图中的a为5,b为126 先把a的原码写出来相加得出来后8位,首先看最高位是0或者1,是1补1,是0补0,得出来的是补码,因为整数在内存中的存储是补码形式的,然后-1取反得原码,因为打印的都是以原码形式打印的。
a与b会发生整形提升,a与b的值会发生变化。

无符号的数发生整形提升,高位补0

上面的这些大小都小于int类型
下面讨论大小大于或者等于int类型的整形提升

这些类型都是向上转换的。

数据存储



有符号数直接用int或者 signed int类型的
无符号直接用unsigned int 类型的

无符号不分最高位是正数还是负数,统一正数。


整形在内存中以补码形式存储


1+-1是通过补码形式实现+-的
原码取反+1得补码
补码取反+1得原码


把一个数的高位字节序内容放在低地址处,把一个低位字节序内容放在高地址处。这个叫大端存储
把一个数的高位字节序内容放在高地址处,把一个低位字节序内容放在地地址处 这个叫小端存储

放与拿相反。比如放进去的是44 33 22 11,拿出去的是11 22 33 44
vs里存的是小端存储模式



主要看起始地址,对起始地址解引用看是不是1还是0,并且还要强制类型转换成char*类型,int类型一次性访问4个字节。





由于c是无符号数,整形提升的时候最高位是1,由于是无符号数,前面直接补0,所以是255,正数的原码补码,反码一样。

