一,进制转换
二进制,八进制,十进制,十进制,十六进制
因为现在的CPU只能识别高低电平,只能对二进制的数据进行计算
虽然二进制的数据可以直接被CPU计算,但是不方便书写,记录,把二进制的数据转换成八进制是为了方便把数据记录到文档中
由于CPU位数的不断发张,有8位逐渐发展到现在的64位,因此八进制不能满足要求,所以发展出了十六进制,但是由于历史原因八进制还不能完全淘汰
十进制转二进制:(其它进制)
求余法:用2对数据求余,然后继续对商求余,直到商为0结束,该过程产生的余数就是该数的二进制(逆序)
n%2 == 1/0
商%2 == 1/0
...
商为0
127 % 2 1
63 % 2 1
31 % 2 1
15 % 2 1
7 % 2 1
3 % 2 1
1 % 2 1
0
01111111
求权法:...256 128 64 32 16 8 4 2 1
从高位到低位 数据 - 2^(n-1) 如果够减,那么第n位就是1,否则是0,直到把数据减为0
86 01010110
72 01001000
112 01110000
176 10110000
二进制转十进制:(其他进制转十进制)
每位的2^(n-1)求和
二进制转八进制:
从低位开始,每三位二进制对应一位八进制
二进制 1|001|010|101|110
八进制 1 1 2 5 6
二进制转十六进制,每四位二进制对应一位十六进制
二进制 1|0010|1010|1110
十六进制 1 2 A E
在C语言中以0开头的数一定是八进制的数,以0X开头的数是十六进制
%o 以八进制显示数据
%x 以十六进制显示数据
%#ox 把数据对应的前缀显示出来
二,原码,反码,补码:
原码:数据的二进制
反码:
正数反码就是它的原码
负数的反码就是它的原码的除符号位外,其它位按位取反
补码:
正数补码就是它的原码
负数的补码就是它的反码+1
tap:内存中所有的数据的存储都是以补码形式储存的
补码怎么转数据:
无符号数据补码直接转换成十进制
有符号最高位是0,说明是正数,也直接转换成十进制
有符号且最高位为1:
1,补码-1得到反码
2,符号位不变,其他位按位取反得到原码
3,原码转换成十进制
三,位运算符 & | ~ ^ << >>
A & B 按位相与
A 00110010 0x32
B 11001010 oxCA
00000010 0x2
A | B 按位相或
A 00110010 0x32
B 11001010 0xCA
11111010 0xFA
~ A 按位求反
A ^ B 按位异或 相同为0,相异为1
A 00110010 0x32
B 11001010 0xCA
11111000 0xf8
A << n 把A的补码向左移n位,左边丢弃,右边补0
0x32 << 3
A 00110010 0x32
10010000 0x90
A >> n 把A的补码向有移n位,右边丢弃,左边补符号位
A 10110010 0x32
11110110
四,函数
一段具有某项功能的代码段,C语言中管理代码的最小单位
把代码封装成一个个函数,可以方便管理和调用代码
函数的分类:
标准库函数
由C语言标注委员会为C语言以函数的形式提供的一些基础功能,被封装libc.so中,使用时需要包含对应的头文件,通过
函数名(实参)方式即可调用标准库中的函数。
系统函数
是操作系统以函数接口形式提供的一系列功能,但它不是真正意义上的函数
内存管理,文件管理,文件IO,信号处理,进程管理,进程通信,线程管理,线程同步,网络通信
第三方函数
由第三方提供的开源或者是收费的代码库
MD5 加密算法
Json 序列化,反序列化
Xml 配置文件的解析算法
自定义函数
为了更好的管理自己的代码,减少代码的冗余把代码封装成函数形式
函数声明:
为了告诉其他人该函数的调用格式
隐式声明:在调用函数时,前面没有出现过该函数的声明或定义,就会产生隐式声明的警告。(不要产生)
返回值类型 函数名(类型1 形参名,类型2 形参2,...);
tap:1,函数名一般建议全小写,可以用下划线分隔
2,如果返回值不需要,则写void
3,如果不需要形参,建议也写void
4,就算形参类型相同,每个都要加类型名
函数定义:函数的实现代码
返回值类型 函数名(类型1 形参名,类型2 形参2,...)
{
//函数体
return(val);
}
函数调用:
函数名(实参);
tap:1,在函数调用之前有函数定义,函数声明可以省略
2,函数的返回值会返回在调用的位置,可以立即显示,也可以用变量记录下来
3,一个函数建议最好不要超过50行代码
一,函数传参
1,形式变量,函数内定义的变量都只属于它所在的函数,出了该函数就不能再用
2,普通实参与形参之间是通过赋值的方式传递数据的(单向值传递,只能实参传形参)
3,return其实是把数据存放到一个公共区域(函数都可以访问),如果不写return,那么就会读取该区域原来的数值,就得到一个垃圾数据。
4,当数组作为函数的参数是,中括号中的长度会丢失,需要额外增加一个变量来传递数组的长度
5,数组作为函数参数传递时,传递的是数组的首地址,叫做‘址传递’,函数和函数的调用者可以共享同一个数组
二,设计函数的建议
1,一个函数最好就解决一个问题,降低错误率,提高可读性
2,尽量减少函数之间的依赖层数(降低耦合度)
3,数据由调用者提供,结果返回给调用者(提高通用性)
4,考虑函数的非法参数,可以通过返回值的方式告诉调用者参数有误,也可以通过注释方式写明情况(提高函数的健壮性)
双色球:
从33个红球挑6个不重复的,从16个篮球挑1个
#include#include #include int main(int argc,const char* argv[]) { srand(time(NULL));//设置随机种子 int arr[7]={},red,flag=0;//存放比较红球数组 printf("红球:"); for(int i=1;i<=6;i++)//抓取6个红球 { red=rand()%33+1; arr[i]=red; for(int j=0;j 输出整数的补码:
#include#include int main(int argc,const char* argv[]) { int num=0; char arr[32]={}; printf("输入一个整数:"); scanf("%d",&num); for(int i=0;i<32;i++) { arr[i] = num >> i & 1; } for(int i=31;i>=0;i--) { printf("%hhd",arr[i]); } } 大数阶乘:
#includeint main() { char arr[2000];//储存结果的每一位的数组 int temp,digit,n;//temp每次的得数 printf("请输入一个整数:"); scanf("%d",&n); arr[0]=1;//从1开始乘 digit=1;//当前结果的最高位的下一位 for(i=2;i<=n;i++) { int num=0;//进位值 for(j=0;j =0;i--)//倒序输出每一位 printf("%hhd",arr[i]); printf("n"); } 函数显示大范围回文数:
#include#include bool is_hui(int num); int main(int argc,const char* argv[]) { for(int i=100000000;i<1000000000;i++) { if(is_hui(i)) printf("%d ",i); } } bool is_hui(int num) { int i=0,s=0; s=num; while(s>0) { i = i*10+s%10; s = s/10; } return(i == num); }



