整型提升
int main(){
char c = 0;
printf("sizeof(c): %d\n", sizeof(c));
printf("sizeof(c): %d\n", sizeof(~c));
printf("sizeof(c): %d\n", sizeof(c << 1));
printf("sizeof(c): %d\n", sizeof(c >> 1));
return 0;
}
char类型是1字节为什么后面哪三个算着是4字节呢
无论任何位运算符,目标都是要计算机进行计算的,而计算机中只有CPU具有运算能力(先这样简单理解),但计算的数据都在内存中。故,计算之前(无论任何运算),都必须将数据从内存拿到CPU中,拿到CPU哪里呢?毫无疑问,在CPU 寄存器中。 而寄存器本身,随着计算机位数的不同,寄存器的位数也不同。一般,在32位下,寄存器的位数是32位。 可是,你的char类型数据,只有8比特位。读到寄存器中,只能填补低8位,那么高24位呢? 就需要进行“整形提升”
左移与右移
(左移): 最高位丢弃,最低位补零 (右移):1. 无符号数:最低位丢弃,最高位补零[逻辑右移] 2. 有符号数:最低位丢弃,最高位补符号位[算术右移]
解释:基本理解链: << 或者 >> 都是计算,都要在CPU中进行,可是参与移动的变量,是在内存中的。 所以需要先把数据移动到CPU内寄存器中,在进行移动。 那么,在实际移动的过程中,是在寄存器中进行的,即大小固定的单位内。那么,左移右移一定会有位置跑到"外边"的情况 
深度理解左移右移
逻辑左移
int main(){
unsigned int a = 1;
printf("%u\n", a << 1);
printf("%u\n", a << 2);
printf("%u\n", a << 3);
return 0;
}
 逻辑右移
int main(){
unsigned int b = 100;
printf("%u\n", b >> 1);
printf("%u\n", b >> 2);
printf("%u\n", b >> 3);
return 0;
}
 算术右移
int main(){
int c = -1;
printf("%d\n", c >> 1);
Show(c>>1);
printf("%d\n", c >> 2);
Show(c >> 2);
printf("%d\n", c >> 3);
Show(c >> 3);
return 0;
}
 算数右移最高位补符号位
在看看这个情况呢!
int main(){
unsigned int d = -1;
printf("%d\n", d >> 1);
Show(d >> 1);
printf("%d\n", d >> 2);
Show(d >> 2);
printf("%d\n", d >> 3);
Show(d >> 3);
return 0;
}

-1存的的时候不看类型直接按补码存到内存 在内存进行移位计算的时候,看的是类型而不是符号位。 只有把数据取出来的时候才看符号位 总结:左移无脑补0 右移就要看类型了,逻辑右移最高位补0,算术右移 最高位补符号位
移位运算的优先级
int main(){
printf("%d\n", 0x01 << 2 + 3);
printf("%d\n", 0x01 << (2 + 3));
printf("%d\n", (0x01 << 2) + 3);
return 0;
}
自行测试

++和 - -
int main(){
int a = 0;
int b = ++a;
printf("a=%d b=%d \n", a, b);
return 0;
}
前置+ 先自增在使用 前置- 同理
int main(){
int a = 0;
int b = a++;
printf("a=%d b=%d \n", a, b);
return 0;
}
后置+ 先使用后自增 后置- 同理
深入理解a++
深入理解a++,a++你明白了,什么++a 呀,就明白了,干就完了
#include<stdio.h>
int main(){
int a = 8;
int b = a++;
printf("%d %d\n", a, b);
return 0;
}
 相信大家对这个应该能够理解,但是编译器内部咋实现的呢,我们看一下反汇编,不会也没事很简单一看就懂; 这下可以明白a++的本质了吧
那如果是a++完之后补赋值呢,会怎么样呢
#include<stdio.h>
int main(){
int a = 8;
a++;
return 0;
}

其实再没有赋值的时候,前置+和后置+都是一样的
来看一组极为不推荐的代码
#include<stdio.h>
int main(){
int i = 1;
int j = (++i) + (++i) + (++i);
printf("%d\n", j);
return 0;
}
结果是12!!! 为啥呢? 解释 
要他妈写这代码就得骂娘了,每个编译器执行的顺序是不一样的
贪心算法
 就是这个样子,但是有时编译器也会分辨不出来,禁止这样写!!!  完结
|