3. 处理数据

68 阅读10分钟

3. 处理数据


3. 处理数据命名规则数据长度数据存储方式整型数据总则char 字符类型浮点类型CPP运算符REF

命名规则

  1. 总则

    1. 不使用非约定成俗的缩写
  2. 文件命名

    1. 文件名全部小写
    2. 可以使用_ 来隔开每个单词
  3. 类型命名

    1. 类型指,类、结构体、类型定义(typedef)、枚举、类型模板参数

    2. 以大写字母开始

    3. 每个字母的首字母大写

    4. 不包含下划线_

    5. EX:

      // 类和结构体
      class UrlTable {...}
      struct UrlTablePropertiesies {...}
      ​
      // 类型定义
      typedef hash_map<UrlTablePropertiesies *, string> PropertiesMap;
      ​
      // using 别名
      using PropertiesMap = hash_map<UrlTablePropertiesies *, string>;
      ​
      // 枚举
      enum UrlTableErrors {...}
      
  4. 变量命名

    1. 变量指函数参数、数据成员名

    2. 一律小写

    3. 单词之间使用下划线

    4. 类的成员变量以下划线结尾,结构体不用

    5. 例:

      // 普通成员
      string table_name;
      ​
      // 类数据成员
      class TableInfo 
      {
          private:
          string table_name_;
          static Pool<TableInfo> * pool_;
      }
      ​
      // 结构体变量
      struct UrlTableProperties 
      {
          string name;
          static Pool<UrlTableProperties>* pool;
      }
      
  5. 常量命名

    1. 声明为constconstexpr的变量,或在程序运行期间保持不变的称为常量

    2. 命名以k开头,每个单词首字母大写(双峰命名法)

    3. EX:

      const int kDaysInAWeek = 7;
      
  6. 函数命名

    1. 常规函数使用双峰命名法

    2. 取值和设值函数要求与变量名相匹配

    3. 例:

      // 常规函数
      AddTableEntry();
      DeleteUrl();
      ​
      // 取值函数
      get_count_value();
      set_member_value();
      ​
      
  7. 命名空间命名

    1. 顶级命名空间的名称应是项目名或者代码所属团队名
    2. 不要与std内名称发生冲突
  8. 枚举变量命名

    1. 枚举的名称应与常量一致(K开头,双峰命名),或宏命名法(全部大写,中间用_隔开)

    2. 例:

      // 常量式
      enum UrlTableErrors
      {
          kOK = 0,
          kErrorOutOfMemory,
          kErrorMalformedTnput,
      };
      ​
      // 或 宏的命名方法
      enum AlternateUrlTableErrors {
          OK = 0,
          OUT_OF_MEMORY = 1,
          MALFORMED_INPUT = 2,
      };
      
  9. 宏命名

    1. 尽量不要使用宏

    2. 全部大写

    3. 中间用_隔开

    4. 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}

数据存储方式

  1. 原码、反码、补码

    1. 计算机存储整数、进行计算时的方式是补码,打印在屏幕上的是原码

      1. 正数的原码反码补码相同
      2. 负数的原码 进行 符号位不变、其他位按位取反后得到反码,反码加一得到补码
      3. 符号位,0代表正数,1代表负数
  2. 小数如何计算二进制

    1. 整数部分,除二取余,倒叙排列(直到商为0)

    2. 小数部分,乘2取整,顺序排列,直到整数部分为0或1(不用管小数是否还有余,取足自己想要的精度就好)

    3. 以8.5为例子,

      1. 整数部分:8除以2 = 4,余0;4除以2 = 2,余0;2除以2 = 1, 余0; 1除以2 = 0,余1。结束, 反向排列余数,所以整数部分为1000
      2. 小数部分:0.5 * 2 = 1.0 。此时乘积的小数部分为0,结束。正向排列整数部分,所以为1
      3. 所以8.5的小数部分为1000.1
  3. 整形数据(各种int)(补码方式)

    1. char为例,char占一个字节,8 bit。值0表示为0000 0000。在signed中其最高位被规定为符号位,剩下低7位被用来存储大小,所以他的大小为-2^{7} \sim 2^{7}-1,即-128 ~ 127

      img

      所以,例:

      1. 要想存储一个十进制为127的数据,先写出他的二进制原码0111 1111(商除以2,直到商为0,然后余数按照相反的顺序排列即可得到对应的二进制数字。),取其反码(正数反码、补码、原码都相同)0111 1111,其补码0111 1111,所以 127在计算机中以0111 1111的形式存储。
      2. -128如何存储?先写二进制原码1000 0000,其反码(符号位不变,其他位取反)1111 1111,加一得其补码1 1000 0000。这与0在计算机中存储0000 0000正好分开,所以负数可以比整数多存一位。
  4. 浮点类型(float、double)(IEEE 754),不采取补码

    1. float为例(4 byte),浮点类型在计算机中以科学计数法的形式表示(IEEE规定)。计算公式为(-1)^{s}M2^{E}

      img

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vfSTln2A-1650547207379)(D:/Desktop/重拾java基础/pic/image-20220322083427131.png)]

    2. S(sign) 为符号位

    3. M(fraction) 表示尾数(二进制的小数)部分。表示浮点类型的精度,通过浮点数的二进制规范化而来,会将第一位的1.隐藏起来。

    4. E(exponent) 表示指数部分。共8位。通过阶计算而来,指数 = 阶 + 偏移量。 阶的取值范围为[-127, 128](就这样规定的,所以不是-128~127)。单精度偏移量为127(2^{n-1}-1),双精度偏移1023,

      1. 偏移是为了保持指数的存储始终为正数。啥意思? 就是将有符号数使用了无符号数表示了,从而指数位始终都是一个非负数。如何表示,加上127。如运算后得到指数为-127,偏移后表示为-127 + 127 = 0,在内存中存储为0000 0000。如果得到的是-10,偏移后表示为-10 + 127 = 117,在内存中存储为0111 0101
    5. 如何存储一个float?

      • 规格数:常见的数值

        如20.5的二进制为10100.1。然后把整个二进制转化为以2为底数的指数形式(二进制科学计数法):10100.1 = 1.01001 * 2^{4}。其中1.01001是尾数,4为偏移之前的指数,再加上偏移量127,即为指数部分4 + 127 = 131,转化为八位二进制为1000 0011

        1. 符号位(31)存储,正数, 存为0.

        2. 尾数部分(30~23)存储

          1. 尾数是指将原数据化为二进制小数(整数除以2后反向取余,小数乘以2后正向取整),然后进行小数点偏移后,由小数点前面的隐藏的1和小数点后面的显式位组成。因为科学计数法第一位必然是1(十进制时为1~9,即非零个位数),所以可以将1.隐藏,仅记录剩余的尾数部分01001。尾数共23 bit ,有时尾数不够填满尾数位需要在低位补零,以填满23位 0100 1000 0000 0000 000
          2. 为什么要在低位补零,而不是高位? 因为这是存储的小数,要想想不影响原数值,就应在低位补零。
        3. 指数部分(22~0)存储

          1. 什么是指数部分? 用以表示换算为以2为底的科学表示法的指数的指数部分
          2. 如何计算指数? 二进制科学计数法的指数再加上偏移量。
      • 非规格数:0,和无限接近0的数

        img

      • 特殊数字: 无穷inf,和 NaN

整型数据

总则

  1. 基本整型有char, short, int, long, long long,又分为有符号(signed),无符号(unsigned)版本,共10种
  2. 宽度:用以描述存储整型时使用的内存量,使用的内存越多,则越宽
  3. 可以使用sizeof()运算符来返回类型或者变量的长度,单位为字节
  4. 头文件climits中包含了关于整型限制的信息
  5. 如果变量值超越变量类型的界限将会循环,如有符号整型 int a = 32767, 再加1,则a = -32768。无符号整型unsigned int b = 65535,再加1,则b = 0;(可以从他们在计算机中的存储方式来解释)
  6. 数值表示方式:以数值的前两位来表示数字常量的基数。十进制第一位1~9,二进制,八进制0,十六进制0x,如0xA5为十个16加5个1。
  7. 后缀: 通过后缀来指出常量类型。uU来指出数字常量为无符号整型,L指出为longll指出为long long
int type16 bit OS(Byte)32 bit OS(Byte)64 bit OS(Byte)
char111
short222
int244
long448
long long888
指针248

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';

浮点类型

  1. 默认为double

  2. 以小数点可以浮动而命名,计算机存储他们将其分为两部分:值,及值的放大和缩小。(尾数与指数),所以尾数代表值,指数用以控制小数点的移动

  3. 两种书写方法:标准小数点法(3.1415,2.718)和E表示法±3.45E(or e)±6 (±3.45 \times 10^{±6}),其中可使用E或e。

  4. 设置固定输出:

    \ 定点表示法,且直到小数点后六位。
    cout.setf(ios_base::fixed, ios_base::floatfiled); 
    
  5. 浮点常量:后缀f, Flong 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);

强制类型转换:

  1. 强制类型转换不会改变变量本身,而是会创建一个新的、指定类型的(没用用变量存储,就是一个临时的值)

  2. 强制类型转换运算符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) 不太了解
    */
    

REF