什么是进制?
是一种计数的方式,数值的表示形式。
常见的进制:十进制、二进制、八进制、十六进制
10 进制转 2 进制
除2取余, 余数倒序得到的序列就是二进制表示形式
2 进制转 10 进制
每一位二进制进制位的值 * 2的(当前二进制进制位索引)
2 进制转 8 进制
三个二进制位代表一个八进制位, 因为3个二进制位的最大值是7,而八进制是逢八进一
2 进制转 16 进制
四个二进制位代表一个十六进制位,因为4个二进制位的最大值是15,而十六进制是逢十六进一
16 进制转 2 进制
将16进制的每一位拆成4为二进制位
数据在计算机内部是以补码的形式储存的
-数据分为有符号数和无符号数
无符号数都为正数,由十进制直接转换到二进制直接存储(其实也是该十进制的补码)即可。有符号数用在计算机内部是以补码的形式储存的。( 正数的最高位是符号位0,负数的最高位是符号位1。
对于正数:反码==补码==原码。
对于负数:反码==除符号位以外的各位取反。补码=反码+1)
正数的首位地址为0,其源码是由十进制数转换到的二进制数字
负数的首位地址为1,其源码后面的位也为10进制数转换过去的二进制数字,都是用补码方式表示有符号数的。
为什么要引入反码和补码?
在开始深入学习前, 我的学习建议是先"死记硬背"上面的原码, 反码和补码的表示方式以及计算方法.
现在我们知道了计算机可以有三种编码方式表示一个数. 对于正数因为三种编码方式的结果都相同, 所以不需要过多解释
在计算的时候我们会根据符号位, 选择对真值区域的加减. (真值的概念在本文最开头). 但是对于计算机, 加减乘数已经是最基础的运算, 要设计的尽量简单. 计算机辨别"符号位"显然会让计算机的基础电路设计变得十分复杂! 于是人们想出了将符号位也参与运算的方法. 我们知道, 根据运算法则减去一个正数等于加上一个负数, 即: 1-1 = 1 + (-1) = 0 , 所以机器可以只有加法而没有减法, 这样计算机运算的设计就更简单了.
(1).如果用原码表示, 让符号位也参与计算, 显然对于减法来说, 结果是不正确的.这也就是为何计算机内部不使用原码表示一个数
(2)发现用反码计算减法, 结果的真值部分是正确的. 而唯一的问题其实就出现在"0"这个特殊的数值上. 虽然人们理解上+0和-0是一样的, 但是0带符号是没有任何意义的. 而且会有[0000 0000]原和 [1000 0000]原两个编码表示0.
(3)于是补码的出现, 解决了0的符号以及两个编码的问题。
什么是位运算符?
位运算是指按二进制进行的运算。在系统软件中,常常需要处理二进制位的问题。
C语言供了6个位操作运算符。这些运算符只能用于整型操作数,即只能用于带符号或无符号的char,short,int与long类型。
&按位与
只有对应的两个二进位均为1时,结果位才为1,否则为0
口诀: 同1为1
| 按位或
只要对应的二个二进位有一个为1时,结果位就为1,否则为0
^ 按位异或
当对应的二进位相异(不相同)时,结果为1,否则为0
~ 取反
各二进位进行取反(0变1,1变0)
多个整数相^的结果跟顺序无关。比如5^6^7=5^7^6
左移位运算符
把整数a的各二进位全部左移n位,高位丢弃,低位补0。左移n位其实就是乘以2的n次方
由于左移是丢弃最高位,0补最低位,所以符号位也会被丢弃,左移出来的结果值可能会改变正负性
右移位运算符
- 把整数a的各二进位全部右移n位,保持符号位不变。右移n位其实就是除以2的n次方
先分配字节地址大内存,然后分配字节地址小的内存(内存寻址是由大到小)
因为内存寻址是由大到小,所以先定义的变量的内存地址会比后定义的大
char类型基本概念
char是C语言中比较灵活的一种数据类型,称为“字符型”。它是用来存储字符的,因此可以将一个字符常量赋值给一个字符型变量
C语言提供了以下4种说明符,4个都属于关键字:
short 短型等价于 short int
long 长型等价于 long int
signed有符号型
unsigned 无符号型
- 这些说明符一般就是用来修饰int类型的,所以在使用时可以省略int
- 在64位编译器环境下:
- short占2个字节(16位)
- int占4个字节(32位)
- long占8个字节(64位)。
- 因此,如果使用的整数不是很大的话,可以使用short代替int,这样的话,更节省内存开销。
- ISO制定了以下规则:
- short跟int至少为16位(2字节)
- long至少为32位(4字节)
- short的长度不能大于int,int的长度不能大于long
- char一定为为8位(1字节),毕竟char是我们编程能用的最小数据类型
signed和unsigned
首先要明确的:signed int等价于signed,unsigned int等价于unsigned
signed和unsigned的区别就是它们的最高位是否要当做符号位,并不会像short和long那样改变数据的长度,即所占的字节数。
- signed:表示有符号,也就是说最高位要当做符号位,所以包括正数、负数和0。其实int的最高位本来就是符号位,已经包括了正负数和0了,因此signed和int是一样的,signed等价于signed int,也等价于int。signed的取值范围是-2^31 ~ 2^31 – 1
数组,从字面上看,就是一组数据的意思,没错,数组就是用来存储一组数据的
数组的几个名词
数组:一组具有相同数据类型的数据的有序的集合
数组元素:构成数组的数据。数组中的每一个数组元素具有相同的名称,不同的下标,可以作为单个变量使用,所以也称为下标变量。
数组的下标:是数组元素的位置的一个索引或指示。(从0开始)
数组的维数:数组元素下标的个数。根据数组的维数可以将数组分为一维、二维、三维、多维数组。
数组的分类
- 按存储的内容分类
数值数组:用来存储数值得
字符数组:用来存储字符‘a’
指针数组:用来存放指针(地址)的
结构数组:用来存放一个结构体类型的数据
+... ...
- 按维度分类
一维数组
二维数组
多维数组
数组如果定义数组后,没有初始化,数组中是有值的,是随机的垃圾数,所以如
果想要正确使用数组应该要进行初始化。
注意:对于数组来说,一旦有元素被初始化,其他元素都被赋值0
数组注意事项
在定义数组的时候[]里面只能写整型常量或者是返回整型常量的表达式
[]中不能放变量
只能在定义数组的时候进行一次性(全部赋值)的初始化
数组内部存储细节
存储方式:
1)计算机会给数组分配一块连续的存储空间
2)数组名代表数组的首地址,从首地址位置,依次存入数组的第1个、第2个....、第n个元素
3)每个元素占用相同的字节数(取决于数组类型)
4)并且数组中元素之间的地址是连续。