【C语言学习笔记】进制和位运算


第一部分 进制
一、基本概念
进制就是不同的计数方式,默认情况下写的数字都是十进制的。
(1)二进制:逢2进位,0b或0B开头
    int number2 = 0B1100;
(2)十进制:逢10进位
    int number = 12;
(3)八进制:逢8进位,0开头
    int number3 = 014;
(4)十六进制:逢16进位,0x或0X开头
    int number4 = 0xc;
二、进制的转换(我们需要掌握的是2进制与10进制之间的转换)
(1)二进制转换成十进制
 0b1100 = 0 * 2的0次方 + 0 * 2的1次方 + 1 * 2的2次方+ 1 * 2的3次方
        = 0 + 0 + 4 + 8 = 12
 0b1111 = 1 + 2 + 4 + 8 = 15
(2)十进制转换成二进制
 67 = 64 + 2 + 1 = 2的6次方 + 2的1次方 + 2的0次方
    = 0b1000000 + 0b10 + 0b1
    = 0b1000011
(3)n位进制的取值范围
 2位二进制位的取值范围:0~3  0~2的2次方-1
 3位二进制位的取值范围:0~7  0~2的3次方-1
 n位二进制位的取值范围:0~2的n次方-1
(4)负数在内存中的存储
负数在计算机中以补码的形式存储
1> 原码:原码就是符号位加上真值的绝对值, 即用第一位表示符号, 其余位表示值。例如
+1原码:0000 0000 0000 0000 0000 0000 0000 0001

-1原码:1000 0000 0000 0000 0000 0000 0000 0001
2> 反码:正数的反码是其本身,负数的反码是在其原码的基础上, 符号位不变,其余各个位取反。
+1反码:0000 0000 0000 0000 0000 0000 0000 0001

-1反码:1111 1111 1111 1111 1111 1111 1111 1110
3> 补码:正数的补码就是其本身,负数的补码是在其原码的基础上,符号位不变,其余各位取反,最后+1(即在反码的基础上+1)。
+1补码:0000 0000 0000 0000 0000 0000 0000 0001

-1补码:1111 1111 1111 1111 1111 1111 1111 1111 
三、不同数据类型在内存中的存储细节
    int a = -10;
    char c = 'A';
(1)负数在内存中是以补码表示的,所以-10的二进制是:
-10原码:1000 0000 0000 0000 0000 0000 0000 1010
-10反码:1111 1111 1111 1111 1111 1111 1111 0101
-10补码:1111 1111 1111 1111 1111 1111 1111 0110
(2)字符在内存实际是以整型存储的,通过ACSII码表,'A'对应的是65,char类型占一个字节,所以二进制是:
    65 = 0b0100 0001
(3)内存存储示意图
           【C语言学习笔记】进制和位运算_第1张图片

四、类型说明符(在mac系统下)
(1)修饰长度
short:2字节
long:8字节
long long:8字节
(2)修饰符号位
signed:最高位当符号位,取值范围:2的-31次方~2的31次方-1
unsigned:最高位不当符号位,取值范围:0~2的32次方-1
(3)补充格式符 
    %d\%i 十进制形式输出整数
    %c 输出字符
    %p 输出地址
    %f 输出小数
    %s 输出一个或多个字符
    %o 八进制形式输出整数
    %x 十六进制形式输出整数
    %e 以标准指数形式输出单、双精度浮点数,数字部分小数位为6位
五、char类型在存储中的存储
(1)字符在内存实际是以整型存储的,字符占是1个字节,8位二进位的取值范围是:-128~127。
(2)操作的int数据如果在-128~127范围内,那么可以用char类型代替int,这样做的目的是省内存。
    char c = 'A';
    printf("%d\n", c);    //65
    printf("%c\n", 67);    //C
    
    char c2 = 'A' + 33;
    printf("%c - %d\n", c2, c2);    //b - 98



第二部分 位运算
一、按位与 &
(1)只有对应的两个二进位均为1时,结果位才为1,否则为0。
(2)二进制中,与1相&就保持原位,与0相&就为0。
二、按位或 |
只要对应的两个二进位有一个为1时,结果位就为1,否则为0。
三、按位异或 ^
(1)当对应的二进位相异(不相同)时,结果为1,否则为0。
(2)规律:
1> 相同整数相^的结果是0。比如5^5=0。
2> 多个整数相^的结果跟顺序无关。比如5^6^7=5^7^6
3> 因此得出结论:a^b^a = b
(3)利用异或交换两个变量的值,不实用第三方变量。
int main(void)
{
    int a = 10;
    int b = 11;
    
    a = a ^ b;
    b = a ^ b;
    a = a ^ b;
    
    printf("a=%d, b=%d\n", a, b);
    
    return 0;
}
四、按位取反 ~
对整数a的各二进位进行取反,符号位也取反(0变1,1变0)。
五、左移 a << n
     000 0000 0000 0000 0000 0000 0000 10010  9<<1
     00 0000 0000 0000 0000 0000 0000 100100  9<<2
     
     9<<1 -> 9 * 2的1次方 == 18
     9<<2 -> 9 * 2的2次方 == 36
如果需要计算乘以2的n次方时,用左移,提升性能。
六、右移  a >> n
     00000 0000 0000 0000 0000 0000 0000 100  8>>1
     000000 0000 0000 0000 0000 0000 0000 10  8>>2
     0000000 0000 0000 0000 0000 0000 0000 1  8>>3
     
     8>>1 -> 8/2的1次方 == 4
     8>>2 -> 8/2的2次方 == 2
     8>>3 -> 8/2的3次方 == 1
如果需要计算除以2的n次方时,用右移。


你可能感兴趣的:(【C语言学习笔记】)