一、进制
1. 进制的定义
是一种计数的方式,数值的表示形式
2. 二进制
2.1特点:只有0和1,逢2进1
2.2书写格式:0b或者0b开头
2.3使用场合:二进制指令\二进制文件,变量在内存中就是二进制存储
2.4二进制和十进制的互相转换
2.5 n为二进制位所能表示的数据范围(不考虑负数):0~2的n次方-1
例: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
0b1010 = 10
2.十进制转二进制
67 = 64 + 2 + 1
= 2的6次方 + 2的1次方 + 2的0次方
= 0b1000000 + 0b10 + 0b1
= 0b1000011
3. 八进制
3.1特点:0~7,逢八进一
3.2书写格式:0开头
3.3 八进制和二进制的互相转换
4. 十六进制
4.1特点:0~F,逢十六进一
4.2书写格式:0x或者0X开头
4.3十六进制和二进制的互相转换
5. printf以不同进制形式进行输出
%d 以带符号的十进制形式输出整数(但正整数不输出正号+)
%o 以不带符号的八进制形式输出整数
%x 以不带符号的十六进制形式输出整数
%u 以不带符号的十进制形式输出整数
%c 输出一个字符
%s 输出一个或多个字符
%f 以小数形式输出单、双精度数,默认输出六位小数
%e 以标准指数形式输出单双精度数、数字部分小数位数位6位
6.n位二进制的取值范围
2位二进制位的取值范围:0~3 0~2的2次方-1
3位二进制位的取值范围:0~7 0~2的3次方-1
n位二进制位的取值范围:0~2的n次方-1
二、原码、反码、补码
1.原码
将一个整数,转换成二进制,就是其原码。
如单字节的5的原码为:00000101;-5的原码为1000 0101。
2.反码
正数的反码就是其原码;负数的反码是将原码中,除符号位以外,每一位取反。
如单字节的5的反码为:0000 0101;-5的反码为11111010。
3.补码
正数的补码就是其原码;负数的反码+1就是补码。
如单字节的5的补码为:00000101;-5的原码为11111011。
4. 为什么要引进反码、补码?
引进补码的作用是为了让计算机更方便做减法
补码、反码就是为了简化减法而来的,将减号化为负数,再将负数化为补码求加法所以对于正数来说,跟正数
三、变量的内存分析
1. 字节和地址
为了更好地理解变量在内存中的存储细节,先来认识一下内存中的“字节”和“地址”。
1.1 内存以“字节为单位”
1.2 不同类型占用的字节是不一样的
2. 变量的存储
2.1 所占用字节数跟类型有关,也跟编译器环境有关
例:
int b = 10;
int a = 134;
3.内存规则
内存由大到小寻址
只存储二进制形式
每个变量都有地址:第一个字节的地址就是变量的地址
四、类型说明符
1.类型说明符所占用的内存
int 4个字节 %d
short 2个字节 %d
long 8个字节 %ld
long long 8个字节 %lld
2.signed == signed int
signed 有符号:正数、0、负数
signed int a = 10;
signed a2 = 10;
3.unsigned int == unsigned
unsigned 无符号:0、正数
unsigned int b = 10;
unsigned b2 = 10;
4.long unsigned int == long unsigned
long unsigned int c = 34343;
long unsigned c2 = 423432;
5.short unsigned int == short unsigned
short unsigned int d = 4343;
short unsigned d2 = 43243;
6.short signed int == short signed
short signed int e = 54354;
short signed e2 = 434;
7.long == long int
long int a = 100645654654645645l;
long a2 = 100645654654645645l;
8.long long int == long long
long long int c = 100645654654645645ll;
long long c2 = 4535435435435ll;
9.short == short int
short int d = 5454;
short d2 = 43434;
10.signed和unsigned的区别:
signed 最高位要当做符号位
unsigned 最高位不要当做符号位
五、位运算
1. & 按位与
1.1功能
只有对应的两个二进位均为1时,结果位才为1,否则为0。
1.2按位与 &
10111011
10101101
--------------
10101001
2. | 按位或
2.1功能
只要对应的二个二进位有一个为1时,结果位就为1,否则为0。
1001
0101
--------
1101
3. ^ 按位异或
3.1功能
当对应的二进位相异(不相同)时,结果为1,否则为0。
1001
0101
--------
1100
总结:
1.相同整数相^的结果是0。比如5^5=0
2.多个整数相^的结果跟顺序无关。比如5^6^7=5^7^6
3.因此得出结论:a^b^a = b
4. ~ 取反
对整数a的各二进位进行取反,符号位也取反(0变1,1变0)
0000 0000 0000 0000 0000 0000 0000 1001
1111 1111 1111 1111 1111 1111 1111 0110
5. << 左移
把整数a的各二进位全部左移n位,高位丢弃,低位补0。左移n位其实就是乘以2的n次方
例:
0000 0000 0000 0000 0000 0000 0000 0000
00 0000 0000 0000 0000 0000 0000 100100
9<<1 -> 9 * 2的1次方 == 18
9<<2 -> 9 * 2的2次方 ==36
9<<n -> 9 * 2的n次方
6. >> 右移
l 把整数a的各二进位全部右移n位,保持符号位不变。右移n位其实就是除以2的n次方
l 为正数时, 符号位为0,最高位补0
l 为负数时,符号位为1,最高位是补0或是补1 取决于编译系统的规定
例:
0000 0000 0000 0000 0000 0000 0000 0000
000000 0000 0000 0000 0000 0000 0000 10
111111 1111 1111 1111 1111 1111 1111 10
8>>1 -> 8/2 == 4
8>>2 -> 8/2的2次方 == 2
8>>n -> 8/2的n次方
六、char类型
1. 存储细节
ASCII单字节表(双字节GBK\GB2312\GB18030\Unicode)
2. 常见错误
char c = A;
char c = "A";
char c = 'ABCD';
char c = '男';
3. 当做整型使用
在-128~127范围内,可以当做整数来用
七、数组
1. 格式
元素类型 数组名[元素个数];
比如:int ages[3];
2. 初始化
2.1初始化方式
int a[3] = {10, 9, 6};
int a[3] = {10,9};
int a[] = {11, 7, 6};
int a[4] = {[1]=11,[0] = 7};
2.2常见错误
int a[];
int[4] a;
int a[b];
a = {10, 11};
a[4] = {10,9,8,5};
3. 基本应用
2.1简单初始化:int ages[5] = {19, 19, 20, 21, 25};
2.2元素有顺序之分,每个元素都有一个唯一的下标(索引),从0开始
2.3数组元素的访问:a[i]
4.其他应用
int maxOfArray(int array[], int length)
{
// 数组当做函数参数传递时,会当做指针变量来使用,指针变量在64bit编译器环境下,占据8个字节
//int size = sizeof(array);
//printf("array=%d\n", size);
//sizeof(array);
// 1.定义一个变量存储最大值(默认就是首元素)
int max = array[0];
// 2.遍历所有元素,找出最大值
for (int i = 1; i<length; i++)
{
// 如果当前元素大于max,就用当前元素覆盖max
if (array[i] > max)
{
max = array[i];
}
}
return max;
}
5.二维数组
int ages[3][5]= {
{10, 11, 90, 89, 70},
{10, 11, 90, 89, 70},
{10, 11, 90, 89, 70}
};