基础1
// ============== 进制
所谓二进制就是逢2补0进1,十六进制就是逢16补0进1
二进制: 1 10 11 100 101 110 111 1000 (十进制:1 ~ 8)
十六进制:8 9 A B C D E F 10 ( 十进制:8 ~ 16)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
在现代的计算机中主要采用的数字集成电路完成,数字电路通过高低电平只能表示0和1,所以就出现了,计算机只会识别0和1。
无论是存储还是计算,计算机均采用二进制体系完成
或者说在电路中,只有两种情况,要么是通路,要么是断路,通路即是1,短路即是0。
以计算机为例,某一时刻,它内部的电路状态永远只有上述两种情况,所以我们的计算机只能处理二进制数据,即0和1
// ============== 简单数据转换
- 传统的计算机存储和数据传输(写代码)
- 8bit = 1Byte、1024Byte = 1KiB、1024KiB = 1MiB、1024MiB = 1GiB、1024GiB = 1TiB
- 网络带宽:
- Mb: 兆比特、MB: 兆字节
- 8bit = 1Byte、1000Byte = 1KB、1000KB = 1MB、1000MB = 1GB、1000GB = 1TB
- 8Kb = (8 / 8) 1 KB = (1 / 1000 * 8) 0.008 Mb = (1 / 1000) 0.001MB 、 8Mb = (8 / 8) 1MB = (1 / 1000 * 8) 0.008Gb = ( 1 / 1000) 0.001GB
- 相邻的单位 大B 和 大B 之间相差 1000 、小b 和 大B 之间相差 8、小b 和 小b 之间相差 1000 [*/] 8 (先用 1000 转为大B 然后乘或除 8)
注意:
- 一般 b 表示 bit、B 表示 Byte
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
首先什么是字节? 字节,即Byte,是由八个位组成的一个单元,也就是8个bit组成1个Byte。这里的8个位是使用二进制来表示的。即:1表示为 0000 0001。 字,即Word,代表计算机处理指令或数据的二进制数位数,是计算机进行数据存储和数据处理的运算的单位。对于不同位的CPU来说,字也是不相同的。 比如8086CPU,它是16位的,那么对于8086CPU来说,它一次能处理的数据最大就是16位,所以8086CPU中一个字就是16位,也就是两个字节(一个字节是8位)。 即:1表示为:0000 0000 0000 0001。 目前而言,16位CPU基本上属于已经淘汰的,也就在一些开发板上可能还是16位的CPU。现在市面上我们大家都在使用的基本上都是32位,64位的CPU,甚至还有128位的。 那么,对于32位的CPU而言,它的一个字就是32位,也就是4个字节;对于64位的CPU而言,它的一个字则是64位,8个字节。 所以,如果你的CPU位数越高,那么单位时间内能处理的数据也就越多越大,运行的效率和速度也就越高,CPU的性能越好
// ============== c/c++ 各数据类型所占空间大小
32位系统和64位系统对比:除了 * 与long随系统子长变化而变化外,其他的都固定不变:bool 1个字节 、char 1个字节、short 2个字节、int 4个字节、float 4个字节 、doubl 8个字节、long long 8个字节
数据类型 | 16位操作系统(byte) | 32位操作系统(byte) | 64位操作系统(byte) | 取值范围 |
char | 1 | 1 | 1 | -128 ~ 127 |
unsigned char | 1 | 1 | 1 | 0 ~ 255 |
short int / short | 2 | 2 | 2 | -32768~32767 |
unsigned short | 2 | 2 | 2 | 0 ~ 65535 |
int | 2 | 4 | 4 | -2147483648~2157483647 |
unsigned int | 2 | 4 | 4 | 0~4294967295 |
long int / long | 4 | 4 | 8 | -2147483648~2147483647 |
unsigned long | 4 | 4 | 8 | 0~42294967295 |
long long int / long long | 8 | 8 | 8 |
-9223372036854775808 |
double | 8 | 8 | 8 |
1.7E+10的负308次⽅~1.7E+10的正308次⽅ |
float | 4 | 4 | 4 | 3.4E+10的负38次⽅~3.4E+10的38次⽅ |
long double | 10/12 | 10/16 | 有效位10字节。32位为了对齐实际分配12字节;64位分配16字节 | |
指针 | 2 | 4 | 8 | / |
总结:常用的32位操作系统和64位操作系统对比:除了 * 与long随操作系统子长变化而变化外,其他的都固定不变:bool 1个字节 、char 1个字节、 int 4个字节、float 4个字节 、doubl 8个字节、long long 8个字节
扩展1:8bit = 1Byte (字节,即Byte,是由八个位组成的一个单元,也就是8个bit组成1个Byte) 、1024Byte = 1KB、1024KB = 1MB、1024MB = 1GB、1024GB = 1TB
示例1:
uint32_t* pRead = NULL; // 这是 uint32_t 类型的一个指针,它本身的大小是4字节或8字节指向一个内存地址(这个地址一般用16进制来表示)。
pRead = (uint32_t*)malloc(16); // 这是申请16个uint32_t的空间,并返回首地址。当 pRead += 5 时,表示它往后移 5 个 uint32_t 的距离,地址往后偏移 5*4 ,也就是在原地址(16进制)的基础上加上十进制的 5*4。如果使用 memcpy(pRead, pData, Data_Size * sizeof(uint32_t)) 这里复制的字节大小需要自己计算。
short* ts = NULL; // 这是 short 类型的一个指针,它本身的大小是4字节或8字节指向一个内存地址(这个地址一般用16进制来表示)。
short* ts = (short*)malloc(16); // 这是申请16个short的空间,并返回首地址。当 pRead += 5 时,表示它往后移 5 个 short 的距离,地址往后偏移 5*2 ,也就是在原地址(16进制)的基础上加上十进制的 5*2。如果使用 memcpy(pRead, pData, Data_Size * sizeof(short)) 这里复制的字节大小需要自己计算。
// ============== 源码、反码、补码
源码、补码、反码只能应用在 正整数、负整数 中
正整数:源码 = 反码 = 补码
负整数:将源码的符号位不变,其余各位取反,得到反码,再将反码加1得到补码
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
符号位: 在日常的工作中,你肯定听到过以下几个数字:255,127,65535,32767,等等。这些数字是什么意思?猛地看上去不明白,直接懵逼。 首先你要先明白,计算机中一个字节是8位,使用十六进制表示则为两位。 255,十六进制即为:ff,二进制即为:1111 1111,表示为一个字节所能表达最大的数字。 那什么是127呢?这里就需要涉及到有符号数和无符号数,还会涉及到原码、反码和补码。先说有符号数和无符号数。 先弄清楚符号是什么,符号就是指正负符号,即+,-。我们自然数字语言中,数字是存在正负之分的,然而机器却不会明白一个数字的正负,也无法区分正负。 但是机器在处理数据的时候,肯定是要按照且符合我们人类自然数字中的运算逻辑,有正也要有负。 为了让机器的运算能够兼容正负数字处理,所以人们便规定了字节的第七位为符号位,0表示正,1表示负。 所以对于有符号数来说,其第七位为符号位,不算入数值表示,实际用来表达数值的只有剩余的7位。 如果七位全为1,即:0111 1111,数值为+127,所以127表示为一个字节有符号数能表达最大的数字。 下面说 65535,二进制就是:1111 1111 1111 1111 ,使用十六进制就是FFFF,也就是说,这是16位CPU中一个字所能表达最大的数字。 16位cpu中32767也是按照有符号数规则,即第15位为符号位,剩余的15位用来表达数值,如果十五位全为1, 即:0111 1111 1111 1111,数值为32767,所以32767表示为一个字有符号数所能表达最大的数字 示例: int a = 3 ; // int整型为4字节,32个bit位 //源码:00000000 00000000 00000000 00000011 //反码:00000000 00000000 00000000 00000011 //补码:00000000 00000000 00000000 00000011 //因为是正整数所以 源码=反码=补码 int a = -3 ; // int 为整型4个字节32个bit位 //因为是负数,所以最高位是 1 //源码:10000000 00000000 00000000 00000011 //源码符号位不变,其余各个位按位取反,得到反码 //反码:11111111 11111111 11111111 11111100 //反码+1,得到补码 //补码:11111111 11111111 11111111 11111101 注意: 整形表达式计算使用在内存中的是补码,打印和看到的都是源码
// ============== 汇编
RAM 代表随机存取内存,ROM 代表只读内存。 RAM 是易失性内存,用于暂时存储正在处理的文件。ROM 是非易失性内存,用于为电脑长久存储指令
使用D命令查看内存范围FFF00H~FFFFFH的内容。因为寻址是基地址✖16+偏移地址,所以我们先对起始目的地址 FFF00H 进行寻址,确定:FFF0:0;结束目的地址 FFFFFH进行寻址,确定:FFF0:FF。 // 起始地址寻址计算:FFF00H / 16 = FFF0 余 0;结束地址寻址计算:(起始地址) :(FFFFFH - FFF00H) // 结束地址反过来
mov bx,1000H // 将16进制1000复制给bx, debug里面不用加H它默认都是16进制 mov ds,bx // 将bx的值赋给ds. 之所以不直接 mov ds,1000H 因为DS是段寄存器,8086CPU不支持将数据直接送入段寄存器操作. 此时ds里存的就是 1000H 这个地址而不是值. ds 是变量段寄存器存的是地址 mov al,[0] // [0] 默认表示取ds里的地址1000H加上偏移量0,即 1000:0, 也就是说把 1000:0 里对应的值赋给al
mov bx,1000H // 给 bx 里赋值为16进制的1000 mov ds,bx // 将 bx 赋值给 ds mov al,afH // 将 16进制的af赋值给al mov [0],al // 将 al 赋值给 1000:0 这个地址
// ============== printf 打印类型
数据类型 | 打印格式 |
u8 | %d |
s8 | %d |
u16 | %d or %hu |
s16 | %d or %hd |
u32 | %u |
s32 | %d |
u64 | %llu |
s64 | %lld |
int | %d |
unsigned int | %u |
short int | %d or %hd |
long | %ld |
unsigned long | %lu |
long long | %lld |
unsigned long long | %llu |
char | char |
char * | %s |
bool (#define stdbool.h) | %d |
unsigned int/int------>十六进制 | %0x |
unsigned long/long---->十六进制 | %0lx |
long long/unsigned long long ----->十六进制 | %0llx |
unsigned int/int------>八进制 | %0o |
unsigned long/long---->八进制 | %0lo |
long long/unsigned long long ----->八进制 | %0llo |
float | %f |
double | %f or %lf |
科学技术类型(必须转化为double类型) | %e |
限制输出字段宽度 | %x.yf (x:整数长度,y:小数点长度) |
本文来自博客园,作者:封兴旺,转载请注明原文链接:https://www.cnblogs.com/fxw1/p/16986673.html