3. 处理数据
3. 处理数据命名规则数据长度数据存储方式整型数据总则char 字符类型浮点类型CPP运算符REF
命名规则
-
总则
- 不使用非约定成俗的缩写
-
文件命名
- 文件名全部小写
- 可以使用
_来隔开每个单词
-
类型命名
-
类型指,类、结构体、类型定义(
typedef)、枚举、类型模板参数 -
以大写字母开始
-
每个字母的首字母大写
-
不包含下划线
_ -
EX:
// 类和结构体 class UrlTable {...} struct UrlTablePropertiesies {...} // 类型定义 typedef hash_map<UrlTablePropertiesies *, string> PropertiesMap; // using 别名 using PropertiesMap = hash_map<UrlTablePropertiesies *, string>; // 枚举 enum UrlTableErrors {...}
-
-
变量命名
-
变量指函数参数、数据成员名
-
一律小写
-
单词之间使用下划线
-
类的成员变量以下划线结尾,结构体不用
-
例:
// 普通成员 string table_name; // 类数据成员 class TableInfo { private: string table_name_; static Pool<TableInfo> * pool_; } // 结构体变量 struct UrlTableProperties { string name; static Pool<UrlTableProperties>* pool; }
-
-
常量命名
-
声明为
const和constexpr的变量,或在程序运行期间保持不变的称为常量 -
命名以
k开头,每个单词首字母大写(双峰命名法) -
EX:
const int kDaysInAWeek = 7;
-
-
函数命名
-
常规函数使用双峰命名法
-
取值和设值函数要求与变量名相匹配
-
例:
// 常规函数 AddTableEntry(); DeleteUrl(); // 取值函数 get_count_value(); set_member_value();
-
-
命名空间命名
- 顶级命名空间的名称应是项目名或者代码所属团队名
- 不要与
std内名称发生冲突
-
枚举变量命名
-
枚举的名称应与常量一致(
K开头,双峰命名),或宏命名法(全部大写,中间用_隔开) -
例:
// 常量式 enum UrlTableErrors { kOK = 0, kErrorOutOfMemory, kErrorMalformedTnput, }; // 或 宏的命名方法 enum AlternateUrlTableErrors { OK = 0, OUT_OF_MEMORY = 1, MALFORMED_INPUT = 2, };
-
-
宏命名
-
尽量不要使用宏
-
全部大写
-
中间用
_隔开 -
EX:
#define ROUND(X) ... #define PI_ROUNDED 3.0
-
数据长度
-
1位(1 bit):
- 无符号:0或1, 2^{1}
- 有符号:-1或0或1
-
1字节(1 B(byte)) = 8 bit
- 无符号:0~255, 2^{8}
- 有符号-128~127
-
2字节(16 bit)
- 无符号:0~65535, 2^{16}
- 有符号: -32768~32767
-
4字节(32 bit)
- 无符号:2^{32}
-
8字节
- 无符号:2^{64}
数据存储方式
-
原码、反码、补码
-
计算机存储整数、进行计算时的方式是补码,打印在屏幕上的是原码
- 正数的原码反码补码相同
- 负数的原码 进行 符号位不变、其他位按位取反后得到反码,反码加一得到补码
- 符号位,0代表正数,1代表负数。
-
-
小数如何计算二进制
-
整数部分,除二取余,倒叙排列(直到商为0)
-
小数部分,乘2取整,顺序排列,直到整数部分为0或1(不用管小数是否还有余,取足自己想要的精度就好)
-
以8.5为例子,
- 整数部分:8除以2 = 4,余0;4除以2 = 2,余0;2除以2 = 1, 余0; 1除以2 = 0,余1。结束, 反向排列余数,所以整数部分为
1000。 - 小数部分:0.5 * 2 = 1.0 。此时乘积的小数部分为0,结束。正向排列整数部分,所以为
1 - 所以
8.5的小数部分为1000.1。
- 整数部分:8除以2 = 4,余0;4除以2 = 2,余0;2除以2 = 1, 余0; 1除以2 = 0,余1。结束, 反向排列余数,所以整数部分为
-
-
整形数据(各种int)(补码方式)
-
以
char为例,char占一个字节,8 bit。值0表示为0000 0000。在signed中其最高位被规定为符号位,剩下低7位被用来存储大小,所以他的大小为-2^{7} \sim 2^{7}-1,即-128 ~ 127所以,例:
- 要想存储一个十进制为127的数据,先写出他的二进制原码
0111 1111(商除以2,直到商为0,然后余数按照相反的顺序排列即可得到对应的二进制数字。),取其反码(正数反码、补码、原码都相同)0111 1111,其补码0111 1111,所以127在计算机中以0111 1111的形式存储。 - -128如何存储?先写二进制原码
1000 0000,其反码(符号位不变,其他位取反)1111 1111,加一得其补码1 1000 0000。这与0在计算机中存储0000 0000正好分开,所以负数可以比整数多存一位。
- 要想存储一个十进制为127的数据,先写出他的二进制原码
-
-
浮点类型(float、double)(IEEE 754),不采取补码
-
以
float为例(4 byte),浮点类型在计算机中以科学计数法的形式表示(IEEE规定)。计算公式为(-1)^{s}M2^{E} -
S(sign) 为符号位
-
M(fraction) 表示尾数(二进制的小数)部分。表示浮点类型的精度,通过浮点数的二进制规范化而来,会将第一位的
1.隐藏起来。 -
E(exponent) 表示指数部分。共8位。通过阶计算而来,指数 = 阶 + 偏移量。 阶的取值范围为
[-127, 128](就这样规定的,所以不是-128~127)。单精度偏移量为127(2^{n-1}-1),双精度偏移1023,- 偏移是为了保持指数的存储始终为正数。啥意思? 就是将有符号数使用了无符号数表示了,从而指数位始终都是一个非负数。如何表示,加上127。如运算后得到指数为
-127,偏移后表示为-127 + 127 = 0,在内存中存储为0000 0000。如果得到的是-10,偏移后表示为-10 + 127 = 117,在内存中存储为0111 0101。
- 偏移是为了保持指数的存储始终为正数。啥意思? 就是将有符号数使用了无符号数表示了,从而指数位始终都是一个非负数。如何表示,加上127。如运算后得到指数为
-
如何存储一个float?
-
规格数:常见的数值
如20.5的二进制为
10100.1。然后把整个二进制转化为以2为底数的指数形式(二进制科学计数法):10100.1 = 1.01001 * 2^{4}。其中1.01001是尾数,4为偏移之前的指数,再加上偏移量127,即为指数部分4 + 127 = 131,转化为八位二进制为1000 0011-
符号位(31)存储,正数, 存为
0. -
尾数部分(30~23)存储
- 尾数是指将原数据化为二进制小数(整数除以2后反向取余,小数乘以2后正向取整),然后进行小数点偏移后,由小数点前面的隐藏的
1和小数点后面的显式位组成。因为科学计数法第一位必然是1(十进制时为1~9,即非零个位数),所以可以将1.隐藏,仅记录剩余的尾数部分01001。尾数共23 bit ,有时尾数不够填满尾数位需要在低位补零,以填满23位0100 1000 0000 0000 000。 - 为什么要在低位补零,而不是高位? 因为这是存储的小数,要想想不影响原数值,就应在低位补零。
- 尾数是指将原数据化为二进制小数(整数除以2后反向取余,小数乘以2后正向取整),然后进行小数点偏移后,由小数点前面的隐藏的
-
指数部分(22~0)存储
- 什么是指数部分? 用以表示换算为以2为底的科学表示法的指数的指数部分
- 如何计算指数? 二进制科学计数法的指数再加上偏移量。
-
-
非规格数:
0,和无限接近0的数 -
特殊数字: 无穷
inf,和NaN
-
-
整型数据
总则
- 基本整型有
char, short, int, long, long long,又分为有符号(signed),无符号(unsigned)版本,共10种 - 宽度:用以描述存储整型时使用的内存量,使用的内存越多,则越宽
- 可以使用
sizeof()运算符来返回类型或者变量的长度,单位为字节 - 头文件
climits中包含了关于整型限制的信息 - 如果变量值超越变量类型的界限将会循环,如有符号整型
int a = 32767, 再加1,则a = -32768。无符号整型unsigned int b = 65535,再加1,则b = 0;(可以从他们在计算机中的存储方式来解释) - 数值表示方式:以数值的前两位来表示数字常量的基数。十进制
第一位1~9,二进制,八进制0,十六进制0x,如0xA5为十个16加5个1。 - 后缀: 通过后缀来指出常量类型。
u或U来指出数字常量为无符号整型,L指出为long,ll指出为long long
| int type | 16 bit OS(Byte) | 32 bit OS(Byte) | 64 bit OS(Byte) |
|---|---|---|---|
| char | 1 | 1 | 1 |
| short | 2 | 2 | 2 |
| int | 2 | 4 | 4 |
| long | 4 | 4 | 8 |
| long long | 8 | 8 | 8 |
| 指针 | 2 | 4 | 8 |
char 字符类型
char类型是特殊的整型,在默认情况下,char既不是有符号的,也不是无符号的,这由C++的实现决定。
char 用''来表述字符,用" "来表示字符串,使用``来转义。
wchar_t宽字符类型。扩展字符集
char16_t, char32_t:无符号char类型16位与32位,且使用前缀u来表示char16_t字符常量和字符串常量,且使用前缀U来表示char132_t字符常量和字符串常量。例:
char16_t ch1 = u'q';
char32_t ch2 = U'\U0000222B';
浮点类型
-
默认为double
-
以小数点可以浮动而命名,计算机存储他们将其分为两部分:值,及值的放大和缩小。(尾数与指数),所以尾数代表值,指数用以控制小数点的移动
-
两种书写方法:标准小数点法(3.1415,2.718)和E表示法±3.45E(or e)±6 (±3.45 \times 10^{±6}),其中可使用E或e。
-
设置固定输出:
\ 定点表示法,且直到小数点后六位。 cout.setf(ios_base::fixed, ios_base::floatfiled); -
浮点常量:后缀
f, F,long double类型后缀l, L
CPP运算符
+ - * / %, %为取余,两个操作数必须为整数(不是整数也得不到余数)
类型转换: 列表初始化不允许缩窄
const int code = 66;
int x = 66;
char c1 {31325}; // 允许
char c2 {66}; // 允许
char c3 {code}; // 允许
char c4 {x}; // 不允许,x是个变量,编译器不会跟踪x被初始化到它被用来初始化c4这个阶段发生的情况,所以在编译器看来x可能很大。
x = 31325;
char c5 = x; // 这种形式被允许。
// (typeName) value
// typeName (value)
int thorn = 333;
(long) thorn;
long (thorn);
强制类型转换:
-
强制类型转换不会改变变量本身,而是会创建一个新的、指定类型的值(没用用变量存储,就是一个临时的值)
-
强制类型转换运算符
dynamic_cast, const_cast, static_cast, reinterpret_cast,语法xxx_cast < typeName > (expression)/* static_cast < type > (expr) 用以执行非动态类型转换,运行时不进行类型检查来保证转换的安全性。 用于: 基本类型的转换 父指针或引用转换为子类指针或引用(向下转换),子到父(向上转换) dynamic_cast < type > (expr) 带有检验转换有效性的类型转换。什么叫做有效性?指目标类型(type)是被转换类型(expr)的可访问基类(间接或直接)。否者将会返回空(指针) 用于: 在类层次上进行向上转换(指针,引用) const_cast < type > (expr) 用于修改值为const类型或volatile类型的静态变量,使用它可以返回一个指向const或非const的指针。但是不能改变数据的类型,即除const或colatile特征可以不同外,typeName和expr的类型必须相同。 用于: 修改const、volatile类型的值,返回其const/非const,volatile/非volatile类型的值 reinterpret_cast <type> (expr) 不太了解 */