一.进制
1.什么是进制
(1)进制是一种计数的方式,数值的表示形式
(2)进制有很多种,开发目前需要知道的是二进制,八进制,十进制,十六进制
2.二进制
(1)特点:只有0和1,逢2进1
(2)书写格式OB或者Ob开头
(3)使用场合:二进制指令或二进制文件,变量在内存中就是二进制存储的
(4)n位二进制所能表示的数据范围(不考虑负数):0—(2的n次方)-1
(5)二进制转十进制就是拿二进制的每一位乘以2的n次方然后相加(n是低位从0开始依次递增)
(6)十进制转二进制就是除以2,每除一次取余,然后从后往前显示二进制。
3.八进制
(1)特点:0—7,逢八进1
(2)书写格式:O开头
4.十六进制
(1)特点:0—F,逢十六进一(A-10,B-11,C-12,D-13,E-14,F-15)
(2)书写格式:Ox或者OX开头
5.printf中以不同进制形式进行输出
(1)%d(%i):以带符号的十进制形式输出整数(但正数不输出正号+)(int,short)
(2)%o:以不带符号的八进制形式输出整数
(3)%x:以不带符号的十六进制形式输出整数
(4)%u:以不带符号的十进制形式输出整数
(5)%c:输出一个字符
(6)%s:输出字符串
(7)%f:以小数形式输出单,双精度数(float,double),默认输出6位小数
(8)%e:以标准指数形式输出单,双精度数,数字部分小数位数为6位
(9)%ld:long
(10)%lld:long long
(11)%u:unsigned
6.补充:
.089 == 0.089
aeb == a*(10的b次方):e后面必须是整数
二.变量的内存分析
1.字节和地址
(1)内存是以字节为单位的
(2)不同类型占用的字节是不一样的
2.变量的存储
(1)所占的字节数跟类型有关,也跟编译器环境有关
(2)定义变量后,分配存储空间是从大到小寻址,内存分配好后,存放的二进制每个字节低位对应小地址开始存放。如下图number是12,number2是13,他们在内存中的存储情况(地址只是随意写的,也是这种形式递增)
(3)只存储二进制形式(内存中只以0,1存在)
(4)每个变量都有地址:第一个字节的地址就是变量的地址,读取内容就是从变量地址读取,一个字节一个字节读取,先放在低位,然后高位。
(5)查看内存地址的两种方式:%x(内存地址是以16进制表示的)和%p
(6)函数输出整数的二进制形式:
void putBinary(int n)
{
int bits = sizeof(n)<<3; // 算出这个类型一共多少位(占字节*8)
while (bits-->0) { // 根据任何数&1就可以求出最低位的值是0或者1,然后右移位运算1位再&1求出倒数第二位的值,以此类推,直到移完所有位。
printf("%d", n>>bits&1);
if (bits%4==0) printf(" "); // 每4位输入一个空格。
}
printf("\n");
三.类型说明符
1.short和long
(1)不同类型所占用的存储空间
(2)short和long可以提供不同长度的整型数,也就是可以改变整型数的取值范围。在64bit编译器环境下,int占用4个
字节(32bit),取值范围是-231~231-1;short占用2个字节(16bit),取值范围是-215~215-1;long占用8个字节
(64bit),取值范围是-263~263-1
(3)总结一下:在64位编译器环境下,short占2个字节(16位),int占4个字节(32位),long占8个字节(64位)。因此,
如果使用的整数不是很大的话,可以使用short代替int,这样的话,更节省内存开销。
(4) 世界上的编译器林林总总,不同编译器环境下,int、short、long的取值范围和占用的长度又是不一样的。比如
在16bit编译器环境下,long只占用4个字节。不过幸运的是,ANSI\ISO制定了以下规则:
<1>short跟int至少为16位(2字节)
<2>long至少为32位(4字节)
<3>short的长度不能大于int,int的长度不能大于long
<4>char一定为为8位(1字节),毕竟char是我们编程能用的最小数据类型
(5)可以连续使用2个long,也就是long long。一般来说,long long的范围是不小于long的,比如在32bit编译器环境
下,long long占用8个字节,long占用4个字节。不过在64bit编译器环境下,long long跟long是一样的,都占用8个字节。
(6)还有一点要明确的是:short int等价于short,long int等价于long,long long int等价于long long
2.signed和unsigned
(1)首先要明确的:signed int等价于signed,unsigned int等价于unsigned
(1)首先要明确的:signed int等价于signed,unsigned int等价于unsigned
(2)signed和unsigned的区别就是它们的最高位是否要当做符号位,并不会像short和long那样改变数据的长度,即所占的字节数。
<1>signed:表示有符号,也就是说最高位要当做符号位,所以包括正数、负数和0。其实int的最高位本来就是符号位(int 默认就是有符号的),已经包括了正负数和0了,因此signed和int是一样的,signed等价于signed int,也等价于int。signed的取值范围是-231 ~ 231 - 1
<2>unsigned:表示无符号,也就是说最高位并不当做符号位,所以不包括负数(正数,0)。在64bit编译器环境下面,int占用4个字节(32bit),因此unsigned的取值范围是:0000 0000 0000 0000 0000 0000 0000 0000 ~ 1111 1111 1111 1111 1111 1111 1111 1111,也就是0 ~ (2的32次方)-1
<1>signed:表示有符号,也就是说最高位要当做符号位,所以包括正数、负数和0。其实int的最高位本来就是符号位(int 默认就是有符号的),已经包括了正负数和0了,因此signed和int是一样的,signed等价于signed int,也等价于int。signed的取值范围是-231 ~ 231 - 1
<2>unsigned:表示无符号,也就是说最高位并不当做符号位,所以不包括负数(正数,0)。在64bit编译器环境下面,int占用4个字节(32bit),因此unsigned的取值范围是:0000 0000 0000 0000 0000 0000 0000 0000 ~ 1111 1111 1111 1111 1111 1111 1111 1111,也就是0 ~ (2的32次方)-1
四.位运算
1.按位与(&)
(1)功能:只有对应的2个二进制均为1时,结果才为1,否则为0。
(2)举例: 比如9&5,其实就是1001&101=1,因此9&5=1
(3)规律:二进制中,与1相&就保持原位,与0相&就为0
(4)用一个数&1,如果得到的值等于1是奇数,否则为偶数或者把这个数模运算2,余数为1时奇数,否则为偶数。
2.按位或(|)
(1)功能:只有对应的二进制位中有一个为1时,结果就为1,否则就为0。
(2)举例: 比如9|5,其实就是1001|101=1101,因此9|5=13
3.按位异或(^)
(1)功能:当对应的二进制相异(不相同)时,结构为1,否则为0。
(2)举例:比如9^5,其实就是1001^101=1100,因此9^5=12
(3)规律:
<1>相同整数相^的结构为0。比如5^5 = 0
<2>多个整数相^的结果跟顺序无关。5^6^7 = 5^7^6
<3>任何数值跟0进行异或,结果还是原来的数值,9^0 == 9
<4>因此得出结论:a^b^a = b
(4)交换a,b的值
<1>设置中间变量交换
<2> a = b - a
b = b - a
a = b +a
<3> a = a ^ b
b = a ^ b
a = a ^ b
4.取反(~)
对整数a的各二进位进行取反,符号位也取反(0变1,1变0)
5.左移(<<)
(1)把整数的各个二进制位全部向左移,高位丢弃,低位补0。左移n位其实就是乘以2的n次方
(2)由于左移是丢弃最高位,0补最低位,所以符号位也会被丢弃,左移出来的结果值可能会改变正负性
(3)乘以2的n次方,效率最高的就是左移运算符
6.右移(>>)
(1)把整数的各二进位全部右移,保持符号位不变。右移n位其实就是除以2的n次方
(2)为正数时, 符号位为0,最高位补0
(3)为负数时,符号位为1,最高位是补0或是补1 取决于编译系统的规定
(2)为正数时, 符号位为0,最高位补0
(3)为负数时,符号位为1,最高位是补0或是补1 取决于编译系统的规定
(4)除以2的n次方,效率最高的就是右移运算符
五.char类型
1存储细节
ASCII单字节表(双字节GBK\GB2312\GB18030\Unicode)
ASCII单字节表(双字节GBK\GB2312\GB18030\Unicode)
2.常见错误
char c = A; (字符要加单引号)
char c = "A"; (字符是单引号,双引号是字符串)
char c = 'ABCD';(字符单引号里面只能放一个单字节的)
char c = '男'; (汉子是占3个字节,只能用字符串)
3.当做整型使用
在-128~127范围内,可以当做整数来用
4.%c和%d\%i的使用
printf(“%d”, ‘A’);
printf(“%c”, 68)
5.转义字符
6.写一个函数将小写字母转为大写字母
char upper(char c)
{
// 如果是小写字母,就转成大写
if (c>='a' && c<='z') { // ['a', 'z']
return c - ('a'-'A');
} else {// 如果不是小写字母,返回字母本身
return c;
}
// 如果是小写字母,就转成大写
if (c>='a' && c<='z') { // ['a', 'z']
return c - ('a'-'A');
}
// 如果不是小写字母,返回字母本身
return c;
}