第一节 进 制
1.进制的概念
其实就是一种计数方式,侧重点在于逢多少进一位
2.C语言能够识别的进制
二进制:用0和1来表示每1位逢二进一.
比如110. 每1位只能是0或者1.
在C语言中,如果要写个二进制数那么就必须使用0b前缀.表示这是1个二进制数
int num = 0b110;
C语言没有提供一个格式控制符输出整型变量的二进制形式.
八进制:用 0 1 2 3 4 5 6 7来表示每一位逢八进一.
比如: 0 1 2 3 4 5 6 7 10 11 12 13 14 1516 17 20
在C语言中,要写1个八进制常量整数,使用前缀0.
int num = 010;
%o 格式控制符将整型变量中的数据以八进制形式输出.
十进制:使用 0 1 2 3 4 5 6 7 8 9来表示每一位,逢十进一.
比如 199;
在C语言中写一个整数,这个整数的进制默认就是十进制.
%d将整型变量中的数据以十进制的形式输出.
十六进制:使用 0 1 2 3 4 5 6 7 8 9 ab c d e f来表示每一位,逢16进1.
0 1 2 3 4 5 6 7 8 9 ab c d e f 10 11 12 13 14 比如 1a
在C语言中如果要写一个十六进制的数必须要使用前缀0x
int num = 0x1a;
%x将整型变量中的数据以十六进制的形式输出
3.进制总结.
1). 二进制. 要写1个二进制数据要使用前缀0b;
2). 八进制. 要写1个八进制数据还要使用前缀0;
3). 十进制. 直接写1个整数默认就是十进制.
4). 十六进制.要写1个十六进制的要使用前缀 0x.
格式控制符.
%d 将整型变量的值以十进制的形式输出.
%o 将整型变量的值以八进制的形式输出.
%x 将整型变量的值以十六进制的形式输出.
没有提供输出二进制形式的格式控制符.
1). 二进制的每1为只能是0或者1. 0 1 10 11 100 101 110 111 1000
2). 八进制的每1位只能是0-7之间的整数. 0 1 2 3 4 5 6 710 11 12 13 14 15 15 17 20
3). 十进制的每1为只能是0-9之间的整数. 0 1 2 3 4 5 6 7 8 9 10 1 12
4). 十六进制的每1位只能是 0-9、a-f中的1位.
第二节进制间的转换
1. 将十进制转换为二进制.
除2取余法将余数倒过来.
2. 将二进制转换为十进制.
加权法.
每一位的位数:最右边是低位最右边那1为时第0位.
每1为的数字乘以 2的位数次方. 加起来.
如:1001101
第0位: 1 * 2的0次方 1
第1位: 0 * 2的1次方 0
第2位: 1 * 2的2次方. 4
第3位: 1 * 2的3次方 8
第4位: 0 * 2的4次方 0
第5位: 0 * 2的5次方 0
第6位: 1 * 2的6次方 64
然后将他们的结果加起来就是十进制
1 + 0 + 4 + 8 + 0 + 0 + 64
3. 数码: 0127每1位的数字,就叫做数码
数位:数码在这个数字之中的位数. 10010
基数:每1位运行有多少个数码. 0123就是这个数是1个几进制的数.
位权:数码*(基数的数位次方)
4. 十进制转换为八进制.
除8取余将余数倒过来
5. 八进制转换为十进制
加权法:
将这个8进制的每1个数码的位权加起来.就是其对应的十进制.
6. 二进制转换为八进制.
三合一法则.从低位开始每3个二进制分为1组,高位不够就补0
把每1组二进制转换为1个8进制.再把每1个八进制和起来.
101101001
101 101 001
5 5 1
7. 将八进制转换为二进制.
1拆3法则.将八进制的每1个数码 转换为1个三位的二进制.
1673
001 110 111 011
8. 将十六进制转换为二进制.
一拆四法.把十六进制的每1个数码拆成4个二进制位.把这些二进制位结合起来.
9a1b
1001 1010 0001 1011
9. 把二进制转换为十六进制.
四合一法则从低位到高位将每四个二进制组成1组 高位不足四位就补0.
再算出每1组的十六进制数.
10011110011011101
0001 0011 1100 1101 1101
1 3 c d d
第三节 原码、反码、补码
1. 任何数据存储在内存之中都是存储的二进制形式.
2. 以整型(int)的数据为例,它是如何存储数据的.
一个int类型的变量在内存占据4个字节.
整型数据是分正负性.
00000000 00000000 00000000 00000011
1个int类型的变量,真正用来存储数据的其实只有31个二进制位.
最高位,并不用来存储数据而是用来表示这个数的正负性.
0 表示这是1个正数.
1 表示这是1个负数.
所以一个整型的变量可以表示的数据 0-2147483647之间.
int num = 9;
00000000 00000000 00000000 00001001
3.原码、反码、补码.
都是二进制的不同的表现形式.数据在内存之中是以补码的形式存储的.
1).原码.
最高位是符号位,其余的二进制位是这个数的绝对值的二进制表现形式.
9
00000000 00000000 00000000 00001001 这就是9的原码.
-3
10000000 00000000 00000000 00000011 这就是-3的原码.
2).反码
a. 正数的反码和原码一样.
b. 负数的反码在原码的基础之上,符号位不变其他位取反.
-3的原码:10000000 0000000000000000 00000011
-3的反码:11111111 1111111111111111 11111100
3).补码:
a. 正数的补码和其原码一样.
b. 负数的补码是在其反码的基础之上加1.
-3的原码:10000000 00000000 00000000 00000011
-3的反码:11111111 1111111111111111 11111100
-3的补码:11111111 1111111111111111 11111101
4). 数据都是以补码的形式存储起来的.
5). 为什么数据要以补码的形式存储
因为计算机之中只有加法没有减法为了更加低成本的算出结果所以使用补码来存储.
第四节位运算
1. 按位运算.
将1个数的二进制位按照每1个二进制位来运算,
注意:按位运算都是按照补码来运算的并且计算出来的结果也是补码.
2. 按位与. &
两个二进制位.进行按位与运算,如果两位都为1结果为1都在就为0.只要有1位为0结果就为0.
4 & -2;
00000000 00000000 00000000 00000100
11111111 11111111 11111111 11111110
------------------------------------------
00000000 00000000 00000000 00000100 +4
-2的原码: 10000000 0000000000000000 00000010
-2的反码: 11111111 1111111111111111 11111101
-2的补码 11111111 11111111 11111111 11111110
任意的数按位与1结果是这个数的最低位.
10 & 1
0000000 0000000 0000000 00001010;
0000000 0000000 0000000 00000001
----------------------------------
0000000 0000000 0000000 00000000
如果这个数的最低位是0那么结果就是0
如果这个数的最低位是1那么结果就是1.
偶数的最低位是0
奇数的最低位是1
所以,要判断1个数是否为偶数,就用这个数&1如果结果为0那么这个时候这个数就是偶数.如果结果为1 那么说明这个数是奇数.
3. 按位或. |
两个二进制数进行按位或运算,只要有1位为1那么结果就是1只有都为0的时候结果才为0.
-3 | -2
-3的原码: 10000000 0000000000000000 00000011;
-3的反码: 11111111 1111111111111111 11111100;
-3的补码: 11111111 1111111111111111 11111101;
-2的原码: 10000000 0000000000000000 00000010
-2的反码: 11111111 1111111111111111 11111101
-2的补码: 11111111 1111111111111111 11111110
11111111 11111111 11111111 11111101;
11111111 11111111 11111111 11111110
--------------------------------------------------------
11111111 11111111 11111111 11111111 这是1个负数是负数的补码.
反码:11111111 1111111111111111 11111110
原码:10000000 0000000000000000 00000001 -1
4. 按位取反: ~这是1个单目运算符.
将参与按位取反的二进制数每1位取反
~3;
00000000 00000000 00000000 00000011;
11111111 11111111 11111111 11111100; 结果是1个负数,这是1个补码.
反码: 11111111 11111111 1111111111111011
原码: 10000000 00000000 0000000000000100
5. 按位异或 ^ shift+6
将参与按位异或的二进制数据每1位相同为0不同为1.
-12 ^ -4;
-12的原码:10000000 0000000000000000 00001100;
-12的反码:11111111 1111111111111111 11110011
-12的补码:11111111 1111111111111111 11110100
-4的原码: 10000000 0000000000000000 00000100;
-4的反码: 11111111 1111111111111111 11111011
-4的补码: 11111111 1111111111111111 11111100
11111111 11111111 11111111 11110100
11111111 11111111 11111111 11111100
-------------------------------------
00000000 00000000 00000000 00001000
交换两个变量的值.
int a = 8;
int b = 4;
a = a ^ b;
b = a ^ b;
a = a ^ b;
6. 按位左移 <<
参与按位左移的二进制位向左移动指定的位数溢出部分丢弃低位补0
3 << 2 12
|00000000 00000000 00000000 00000011|;
|000000 00000000 00000000 0000001100|
按位左移:
1).有可能改变这个数的正负性.
2).1个数按位左移n位.就相当于这个数乘以 2的n次方.
4<<3 4*(2的3次方.)
7. 按位右移 >>
参与按位右移的二进制位,向右移动指定的位数溢出部分丢弃高位补符号位.
8 >> 2;
|00000000 00000000 00000000 00001000|
|0000000000 00000000 00000000 000010|
注意:
a. 按位右移不会改变这个数的正负性.
b. 1个数按位右移n位,就相当于这个数除以2的n次方.
第五节 signed与unsigned
1. int 变量最高位都是用来表示符号位的.
2. unsigned修饰1个int变量.表示这是1个无符号的变量.没有正负性.
这个时候,最高位就不再用来表示正负性.
最高位就直接参与到数据的存储之中.
int num1; 存储数据的只有31位.最高位是用来表示符号的.
unsigned int num1; 全部的位数都用来存储数据.没有负数.
这个时候,全部的位数都用来存储数据那么这个变量中存储的最小值是0.最大值是2的32次方-1
unsigned short int num2 = 0;
这是1个2个字节所以16个位全部用来存储数据. 0 - 2 的16次方-1
unsigned long int num3 = 100;
这是8个字节, 64为都用来存储数据.
总之:
加了unsigned表示这是1个无符号.没有负数.
最高位就不再用来表示符号位了.最小值是0最大值就是2的二进制位次方-1
3. signed修饰的变量表示这是1个有符号的也就是最高位不参与数据的存储只是用来表示这个数据的正负性.
4. 格式符.
整数:
%d 将整数以十进制形式输出.
%o 将整数以八进制形式输出.
%x 将整数以十六进制输出.
%hd 输出1个short修饰的int变量.
%ld 输出1个long修饰的int变量.
%lld 输出1个long long修饰的int变量.
%u 输出1个无符号的整形int变量.
%hu 输出1个无符号的short修饰的int变量.
%lu 输出1个无符号的long修饰的int变.
%llu 输出1个无符号的long long修饰的int变量.
地址: %p
浮点型:
%f
%lf
字符型;
%c