目录
字符的ASCII码
ASCII是基于拉丁字母的一套电脑编码系统。它共定义了128个字符,其中33个字符无法显示,且这33个字符多数都已是陈废的控制字符。控制字符的用途主要是用来操控已经处理过的文字,在33个字符之外的是95个可显示的字符。计算机中的数据本质上都是二进制数据,所以字符也能够用二进制信息来表示。如下
ASCII控制字符(33个):
二进制 | 十进制 | 十六进制 | 缩写 | 可以显示的表示法 | 名称/意义 |
---|---|---|---|---|---|
0000 0000 | 0 | 00 | NUL | ␀ | 空字符(Null) |
0000 0001 | 1 | 01 | SOH | ␁ | 标题开始 |
0000 0010 | 2 | 02 | STX | ␂ | 本文开始 |
0000 0011 | 3 | 03 | ETX | ␃ | 本文结束 |
0000 0100 | 4 | 04 | EOT | ␄ | 传输结束 |
0000 0101 | 5 | 05 | ENQ | ␅ | 请求 |
0000 0110 | 6 | 06 | ACK | ␆ | 确认回应 |
0000 0111 | 7 | 07 | BEL | ␇ | 响铃 |
0000 1000 | 8 | 08 | BS | ␈ | 退格 |
0000 1001 | 9 | 09 | HT | ␉ | 水平定位符号 |
0000 1010 | 10 | 0A | LF | ␊ | 换行键 |
0000 1011 | 11 | 0B | VT | ␋ | 垂直定位符号 |
0000 1100 | 12 | 0C | FF | ␌ | 换页键 |
0000 1101 | 13 | 0D | CR | ␍ | 归位键 |
0000 1110 | 14 | 0E | SO | ␎ | 取消变换(Shift out) |
0000 1111 | 15 | 0F | SI | ␏ | 启用变换(Shift in) |
0001 0000 | 16 | 10 | DLE | ␐ | 跳出数据通讯 |
0001 0001 | 17 | 11 | DC1 | ␑ | 设备控制一(XON 启用软件速度控制) |
0001 0010 | 18 | 12 | DC2 | ␒ | 设备控制二 |
0001 0011 | 19 | 13 | DC3 | ␓ | 设备控制三(XOFF 停用软件速度控制) |
0001 0100 | 20 | 14 | DC4 | ␔ | 设备控制四 |
0001 0101 | 21 | 15 | NAK | ␕ | 确认失败回应 |
0001 0110 | 22 | 16 | SYN | ␖ | 同步用暂停 |
0001 0111 | 23 | 17 | ETB | ␗ | 区块传输结束 |
0001 1000 | 24 | 18 | CAN | ␘ | 取消 |
0001 1001 | 25 | 19 | EM | ␙ | 连接介质中断 |
0001 1010 | 26 | 1A | SUB | ␚ | 替换 |
0001 1011 | 27 | 1B | ESC | ␛ | 跳出 |
0001 1100 | 28 | 1C | FS | ␜ | 文件分割符 |
0001 1101 | 29 | 1D | GS | ␝ | 组群分隔符 |
0001 1110 | 30 | 1E | RS | ␞ | 记录分隔符 |
0001 1111 | 31 | 1F | US | ␟ | 单元分隔符 |
0111 1111 | 127 | 7F | DEL | ␡ | 删除 |
ASCII可显示字符(95个):
|
|
|
在C中,char实质上是以int存储的,char与int可互相转换(前提是int不能char的取值范围0~127,char是不为负值的signed类型)。同一段二进制码,输出的形式不同(char/int),得到的结果也不同。如下图和代码段:
#include <stdio.h>
int main() {
char ch = '!';
int i = 33;
printf("%d,%c\n", ch, i);
return 0;
}
//输出 33 !
转义字符
所有的ASCII码都可以用反斜杠“\”加数字来表示(一般是8进制数字,如果用其他进制表示,可能会出错)。
#include <stdio.h>
int main() {
char ch = 35;
char ch1 = '\035'; //代表int型29:3×8 + 5 = 29
printf(%c,%c\n", ch, ch1);
return 0;
}
而C中定义了一些字母前加 "\" 来表示常见的那些不能显示的ASCII字符,如\0,\t,\n等,称为转义字符,因为后面的字符,都不是它本来的ASCII字符意思了。并且下面的字符都只算一个char字符,
转义字符 | 意义 | ASCII码值(十进制) |
\a | 响铃(BEL) | 007 |
\b | 退格(BS) ,将当前位置移到前一列 | 008 |
\f | 换页(FF),将当前位置移到下页开头 | 012 |
\n | 换行(LF) ,将当前位置移到下一行开头 | 010 |
\r | 回车(CR) ,将当前位置移到本行开头 | 013 |
\t | 水平制表(HT) (跳到下一个TAB位置) | 009 |
\v | 垂直制表(VT) | 011 |
\\ | 代表一个反斜线字符''\' | 092 |
\' | 代表一个单引号(撇号)字符 | 039 |
\" | 代表一个双引号字符 | 034 |
\? | 代表一个问号 | 063 |
\0 | 空字符(NUL) | 000 |
\ddd | 1到3位八进制数所代表的任意字符 | 三位八进制 |
\xhh | 十六进制所代表的任意字符 | 十六进制 |
思考:
关于字符串中的转义字符,上述的反斜杠加一个字母如 \n 都是算一个char,而字符串 " \\t "则有两个字符 ' \\ ' 和 ' t ' 构成。见如下代码:
#include <iostream>
#include <string>
using namespace std;
int main(){
string a0="a\tb";
string a1="a\\tb";
string a2="a\\\tb";
string a3="a\\\\tb";
cout<<a0<<endl;
cout<<a1<<endl;
cout<<a2<<endl;
cout<<a3<<endl;
return 0;
}
输出:
a b
a\tb
a\ b
a\\tb
如果反斜杠与字母的组合超过了一个char,那么他们不再是一个转义字符,而是一个转义字符加上其他的字符。
关于补码
定点数据和浮点数据在计算机中都是以补码形式存储的。补码可以将减法运算变为加法运算,简化计算机的运算。
正数的补码是其本身,负数的补码等于将原码除符号位取反后在加一,同样的,从负数的补码到原码,是将补码除了符号位取反后再加一。
对于>>和<<这样的位移操作,正数可以直接在其原码上进行,空位补0,而负数的移位操作都要在补码上进行。关于负数的补码有这样一个特点:
如下,在负数的补码中,当对其由低位向高位找到第一个“1”时,在此“1”左边的各位均与对应的反码相同,而在此“1”右边的各位(包括此“1”在内)均互对应的原码相同。
原码: 101011001000
反码: 110100110111
补码: 110100111000
因此负数的补码左移时,因空位出现在低位,则添补的代码与原码相同。即整体左移,右端添 0;右移时因空位出现在高位,则添补的代码应与反码相同,即整体右移,左端空位添1。
为什么负数要用补码表示?
负数之所以用补码的方式来表示,主要是为了统一和正数的加减法操作一样,毕竟数字的加减法是很常用的一个操作,就不要搞特殊化,尽量以统一的方式来运算。
十进制小数怎么转成二进制?
十进制整数转二进制使用的是「除 2 取余法」,十进制小数使用的是「乘 2 取整法」。
计算机是怎么存小数的?
计算机是以浮点数的形式存储小数的,大多数计算机都是 IEEE 754 标准定义的浮点数格式,包含三个部分:
-
符号位:表示数字是正数还是负数,为 0 表示正数,为 1 表示负数;
-
指数位:指定了小数点在数据中的位置,指数可以是负数,也可以是正数,指数位的长度越长则数值的表达范围就越大;
-
尾数位:小数点右侧的数字,也就是小数部分,比如二进制 1.0011 x 2^(-2),尾数部分就是 0011,而且尾数的长度决定了这个数的精度,因此如果要表示精度更高的小数,则就要提高尾数位的长度;
用 32 位来表示的浮点数,则称为单精度浮点数,也就是我们编程语言中的 float 变量,而用 64 位来表示的浮点数,称为双精度浮点数,也就是 double 变量。
主存 辅存 机器指令的存取
主存相当于内存条,辅存相当于硬盘,U盘。
主存即主存储器,是cpu能直接寻址的空间,主存包括 随机存储器(RAM)、只读存储器(ROM)和高级缓存(Cache)。下图是主存的结构图,其中
- MAR为存储器地址寄存器,记录主存中各个存储单元的地址编号,与cpu通过地址总线相连
- MDR为存储器数据寄存器,与主存的存储单元字长相同,用与主存与cpu交换数据,与cpu通过数据总线相连。
cpu与主存无法进行直接通讯,需要借助MAR和MDR来进行数据的读取。
不过需要注意的是,MDR,MAR虽然是存储起的一部分,在现代CPU中是存在于CPU中的。
机器指令是计算机所能识别并直接执行的一种语言,不同的语言在编译后都会变成机器指令存储在主存中,等待CPU的调用执行。并且这些机器指令的在内存中的地址存储在CPU的程序计数器PC中。
PC与MAR类似,都是存储主存中元素的地址,不同的是,PC专门存储主存中机器指令的地址,并且PC是可读写的,而MAR中存储的是主存中所有数据的地址,他对于用户不可见,无法修改或读取它。
CPU与主存的通讯如下:
关于 (pc)+1→pc 的解释
(pc)指的是pc中的内容,而pc指的就是指这么一个寄存器,(pc)+1指的是把pc中的内容+1,→pc指的是送到pc这个寄存器中,而不是送到pc中的内容中,→应该是赋值的意思
ROM RAM DRAM SRAM
ROM和RAM指的都是半导体存储器,ROM是Read Only Memory的缩写(只读存储器),RAM是Random Access Memory的缩写(随机存储器)。ROM在系统停止供电的时候仍然可以保持数据,而RAM通常都是在掉电之后就丢失数据。
RAM与ROM都是内存,而硬盘是外存,所以ROM不等于硬盘。计算机中的ROM主要是用来存储一些系统信息,或者启动程序BIOS程序。
ROM:只读存储器。在制造ROM的时候,信息(数据或程序)就被存入并永久保存。这些信息只能读出,一般不能写入,即使机器掉电,这些数据也不会丢失。ROM一般用于存放计算机的基本程序和数据,如BIOS ROM。ROM所存数据,一般是装入整机前事先写好的,整机工作过程中只能读出,而不像随机存储器那样能快速地、方便地加以改写。
RAM有两大类:
一种称为 静态RAM(StaticRAM/SRAM),SRAM速度非常快,是目前读写最快的存储设备,但是它也非常昂贵,所以只在要求很苛刻的地方使用,譬如CPU的一级缓冲,二级缓冲。
另一种称为 动态RAM(Dynamic RAM/DRAM),DRAM保留数据的时间很短,速度也比SRAM慢,不过它还是比任何的ROM都要快,从价格上来说DRAM相比SRAM要便宜很多,主要用于系统内存储器,容量大,不需要断电后仍保存数据,计算机内存就是DRAM的。 DRAM分为很多种,其中的一种DDR RAM,它可以在一个时钟读写两次数据,这使得数据传输速度加倍。这是目前电脑中用得最多的内存。
一般对于RAM和ROM的讨论都是限于计算机的内存,与外存的关系不大
对于电脑的外存,有机械硬盘和固态硬盘两种,机械硬盘采用的是磁性材料,通过扫描磁盘来读取数据。固态硬盘用的是半导体材料,有用闪存技术做成的(SSD),也有用SDAM技术做成的,前者数据保护不需要额外电源,后者的数据保护需要额外的电源。