c语言获取字节每个位,【C语言笔记】源码补码反码及位运算

源码补码反码

int main(int argc, const char * argv[])

{

// int占4个字节 1个字节8位

int num = 12;

/*

// 12的二进制

12在内存中存储的是它的补码

00000000 00000000 00000000 00001100

正数的特点:(三码合一) 正数的原码就是TA的反码就是TA的补码

-12

二进制的最高位我们称之为符号位

如果符号位是0代表是一个正数,

如果符号位是1代表是一个负数

10000000 00000000 00000000 00001100 (-12的原码)

11111111 11111111 11111111 11110011(反码, 符号位不变其它位取反)

11111111 11111111 11111111 11110011

+00000000 00000000 00000000 00000001

_____________________________________________

11111111 11111111 11111111 11110100(补码 , 反码+1)

结论:无论正数负数在内存中存储的都是补码

11111111 11111111 11111111 11110101 (补码)

-00000000 00000000 00000000 00000001 (-1)

_____________________________________________

11111111 11111111 11111111 11110100 (反码)

10000000 00000000 00000000 00001011

*/

printf("%d\n", 0b11111111111111111111111111110101);

return 0;

}

位运算

/*

位运算都是针对二进制的

&

|

^

~

<<

>>

*/

int main(int argc, const char * argv[])

{

/*

& 按位与

特点:只有对应的两位都是1才返回1 否则返回0

口诀: 一假则假

规律:任何数按位与上1结果还是那个数

1001

& 0101

_______

0001

1001

&1111

______

1001

*/

/*

| 按位或

特点:只要对应的两位其中一位是1就返回1

口诀:一真则真

1001

| 0101

________

1101

*/

/*

^ 按位异或

特点:对应的两位不相同返回1 相同返回0

1001

^ 0101

_______

1100

// 多个整数按位异或的结果和顺序无关

1001

^ 0101

_______

1100

1100

^ 0110

_______

1010

1001

^ 0110

_______

1111

1111

^ 0101

_______

1010

// 相同整数按位异或结果是0

1001

^ 1001

_______

0000

// 任何整数按位异或上0结果不变

1001

^ 0000

_______

1001

// 任何整数按位异或上另一个整数两次结果还是那个数

1001

^ 1001

____________

0000

0000

^0101

______

0101

*/

// int result = 9 & 5;

// int result = 9 | 5;

// int result = 9 ^ 5;

// 多个整数按位异或的结果和顺序无关

// int result2 = 9 ^ 5 ^ 6;

// int result2 = 9 ^ 6 ^ 5;

// 相同整数按位异或结果是0

// int result3 = 9 ^ 9;

// 任何整数按位异或上0结果不变

// int result4 = 9 ^ 0 ;

// 任何整数按位异或上另一个整数两次结果还是那个数

// int result5 = 9 ^ 9 ^ 5;

// int result6 = 9 ^ 5 ^ 9;

// printf("result = %d\n", result6);

/*

~ 按位取反

特点: 0变1 1变0

0000 0000 0000 0000 0000 0000 0000 1001

~1111 1111 1111 1111 1111 1111 1111 0110 (补码)

0000 0000 0000 0000 0000 0000 0000 0001

______________________________________________

1111 1111 1111 1111 1111 1111 1111 0101 (反码)

1000 0000 0000 0000 0000 0000 0000 1010

*/

// int result = ~9;

printf("result = %d\n", result);

// printf("%d\n",0b11111111111111111111111111110110);

return 0;

}

左移右移

int main(int argc, const char * argv[]) {

/*

<< 左移

a << n 把整数a的二进制位往左边移n位

移出的位砍掉,低位补0, 发现左移会把原有的数值变大

9 << 1 = 18 9 * 2(1) = 18

9 << 2 = 36 9 * 2(2) = 26

9 << n = 9 * 2(n)

左移的应用场景:当要计算某个数乘以2的n次方的时候就用左移,效率最高

0000 0000 0000 0000 0000 0000 0000 0000

100 0000 0000 0000 0000 0000 0000 10010

注意点:左移有可能改变数值的正负性

*/

/*

>> 右移

a >> n 把整数a的二进制位往右边移n位

移出的位砍掉, 缺少的以为最高位是0就补0是1就补1(是在当前操作系统下)

9 >> 1 = 4 9 / 2(1) = 4

9 >> 2 = 2 9 / 2(2) = 2

右移的应用场景:当要计算某个数除以2的N次方的时候就用右移,效率最高

0000 0000 0000 0000 0000 0000 0000 0000

000000 0000 0000 0000 0000 0000 0000 10

*/

// int result = 9 << 2;

int result = 9 >> 2;

printf("result = %d\n", result);

return 0;

}

变量存储细节

int main(int argc, const char * argv[]) {

// 变量为什么要有类型? 每种类型占用的内存空间不一样 int 4, char 1 double 8

// 只要定义变量, 系统就会开辟一块存储空间给我们的变量存储数据, 内存寻址是从大到小

// 越先定义的变量, 内存地址越大

// 变量的地址就是所占的存储空间最小的字节地址

int num;

// 注意: 由于内存寻址是从大到小, 所以存储数据也是从大到小的存储(先存储二进制的高位, 再存储低位)

// 高位 --> 低位

// 00000000 00000000 00000000 00001001

num = 9; // 9 -->二进制 -->存储(补码)

int value;

value = 600; //00000000 00000000 00000010 01011000

// %p是输出地址

// &变量名称, 是取出变量的地址

printf("num = %p\n", &num);

printf("value = %p\n", &value);

// 获取存储的每一位

char *c = &value;

for (int i = 0; i < sizeof(num); i++) {

int result = c[i]; // 取出每个字节中存储的数据

printf("%i\n", result);

}

return 0;

}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值