C++ Primer 0x02 学习笔记

Posted 鱼竿钓鱼干

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++ Primer 0x02 学习笔记相关的知识,希望对你有一定的参考价值。

📔 C++ Primer 0x02 学习笔记

第 2 章 变量和基本类型

2.1 基本内置类型

2.1.1 算术类型

  • 基本内置类型:算术类型和空类型
  • 算术类型:字符、整型数、布尔值、浮点数
  • 除了布尔型和扩展字符型,其他整形可以划分为有符号类型和无符号类型
  • char类型可能带符号,可能不带符号
  • 无符号类型所有比特位用来存值,有符号类型没有规定怎么存,但应当平衡
  • 浮点一般选double,精度比float高,运算代价比long double少,性价比最好

2.1.2 类型转换

  • 整数类型给浮点类型,小数部分为0,如果整数空间超过浮点类型容量,可能会有精度损失
  • 无符号类型表示超范围的数自动取模,模空间大小
  • 带符号类型表示超范围数,结果为定义
  • 不要混用有符号类型和无符号类型,有符号类型会转成无符号类型

2.1.3 字面值常量

  • 整型字面值,0开头为八进制,0x开头为十六进制
  • 十进制整形字面值默认是带符号数,类型是能容纳其大小的最小的类型,short没有对应字面值
  • 负号实际不在字面值里
  • 浮点数字面值表现为一个小数或科学计数法,默认double类型
  • 单引号是字符字面值,双引号是字符串字面值
  • 如果两个字符串字面值位置紧邻且中间只有换行符、空格、缩进,那么他们是整体
  • 字符串字面值实际上是常量字符构成的数字,末尾会加上空字符(’\\0’)
  • 两类字符不能直接打印:不可打印字符、转移序列
  • 可以通过前后缀指定字面值类型,长整型一般用L防止l和1混淆
  • 布尔型字面值 true、false,指针型字面值 nullptr
  • long long c++11

2.2 变量

2.2.1 变量定义

  • 变量的基本形式:类型说明符 + 变量名
  • 初始化不是赋值,初始化的含义是创建变量时赋予一个新值,而赋值的含义是把对象当前的值擦除,用一个新的值代替
  • 列表初始化用,如果存在丢失信息的危险,编译器会拒绝初始化请求
  • 定义变量没有给初始值,那么就会被默认初始化,初始化的值取决于变量类型
  • 内置变量类型如果在函数内部则不被初始化,他的值未定义;如果在所有函数外部,那么初始化为0

2.2.2 变量声明和定义的关系

  • C++支持分离式编译
  • 声明使得名字为程序所知,定义负责创建与名字相关联的实体
  • 如果要声明一个变量而不是定义,那就加上extern并且不要显式地初始化
  • 任何包含显式初始化的声明会变成定义
  • 函数内部初始化一个extern会报错
  • 变量只能被定义一次,但可以声明多次
  • C++是一种静态类型语言,编译过程中会进行类型检查

2.2.3 标识符

  • C++ 标识符 (identifier) 由字母、数字、下划线组成,必须以字母或下划线开头,大小写敏感
  • 关键字保留字不能作为标识符
  • 变量命名规范
    • 标识符体现具体含义
    • 变量名一般小写
    • 自定义类名一般大写字母开头
    • 如果标识符由多个单词组成,单词之间应该有明显区分

2.2.4 名字的作用域

  • 作用域,一般用花括号分割
  • 全局作用域
  • 块作用域
  • 嵌套作用域:内层作用域,外层所用域,注意覆盖问题

2.3 复合类型

2.3.1 引用

  • 引用 (reference) 给对象起了另一个名字,但他不是对象
  • 定义引用的时候必须初始化,并且引用和初始值绑定 (bind) 在一起,而不是拷贝给引用
  • 无法令引用重新绑定到另一个对象
  • 引用不是一个对象,无法定义引用的引用
  • 定义多个引用的时候每个引用标识符都要以&开头
  • 引用类型必须和对象类型严格匹配,不能和字面值或某个表达式的计算结果绑定(常量引用除外,见2.4节 const 限定符)
  • 引用能干什么取决于绑定的对象能干什么

2.3.2 指针

  • 指针本身是对象,允许对指针赋值和拷贝,可以先后指向几个不同的对象
  • 指针无需在定义时赋值,如果没有初始化那就是个不确定的值
  • 定义多个指针,每个前面都要以*开头
  • 指针存放某个对象的地址,要想获取地址就要使用取地址符&
  • 指针类型要和指针对象严格匹配(有两个特例)
  • 指针值应该属于下面四种状态之一
    • 指向一个对象
    • 指向紧邻对象所占空间的下一个位置
    • 空指针
      • nullptr
      • 0,要字面常量,不能是等于0的变量
      • NULL 在cstdlib中被定义为0 (预处理变量不属于命名空间,直接用)
    • 无效指针
  • 利用解引用符* 访问对象,解引用操作只适合指向了某个对象的有效指针
  • 指针相等3种可能
    • 都为空
    • 指向同一个对象
    • 指向同一个对象的下一地址
  • void* 指针
    • 可以存放任意对象的地址
    • 不能直接操作void* 指针所指的对象
    • 可以和其他函数作比较,赋给另一个 void* 指针,作为函数的输入输出
    • void* 视角看内存空间也就只是内存空间,没法访问内存空间中所存的对象

2.3.3 理解复合类型的声明

  • 变量的定义:基本数据类型+一组声明符,类型修饰符如:指针、引用等只是声明符的一部分罢了
  • 指向指针的指针要两次解引用
  • 引用本身不是对象,因此没有指向引用的指针;但是指针有对象,存在指向指针的引用
  • 面对一条比较复杂的指针或引用的声明语句时,从右向左阅读有助于弄清含义,离变量名最近的符号对变量名有着最直接的影响。

2.4 const 限定符

  • const 对象一旦创建后值不能改变, const 对象必须初始化
  • cons t对象被其他对象初始化,它们是不是 const 没关系。牢记初始化和赋值的区别,赋值是擦除旧值,赋予新值,有改变值的含义。
  • 默认状态下,const 对象只在文件内有效,因此如果要多文件共享就要在 const 前加 extern

2.4.1 const的引用

  • 引用绑定到 const 对象上称为对常量的引用 (reference to const),常量引用只是它的简称。实际上不存在常量引用,因为引用不是对象,不能用 const 让它的值不变
  • 对常量的引用不能被用作修改它绑定的对象
  • 不能用一个非常量引用指向一个常量对象
  • 初始化常量引用的时候允许用任意表达式作为初始值,只要能转换成引用的类型即可(中间会产生一个临时量)
  • const 的引用可能引用一个非 const 的对象,这样的话只是限定了通过引用改变对象的值,但是可以通过其他途径去改变

2.4.2 指针和 const

  • 区分指向常量的指针 (pointer to const) 和 const 指针 (const pointer)
  • 指向常量的指针不能用于改变其所指对象的值,存放常量地址的值只能用指向常量的指针
  • 指向常量的指针可以指向非常量
  • const 指针 必须初始化

2.4.3 顶层const

  • 顶层 const 表示 指针本身是个常量,底层 const 表示 指针指向的对象是常量
  • 当执行对象的拷贝操作的时候,两个对象必须有相同的底层 const 资格,或者两个对象的数据类型可以相互转换,一般来说非常量可以转为常量,反之不可以
  • 常量表达式在编译过程中就能得到计算结果,用常量表达式初始化的 const 对象 也是常量表达式
  • 如果认定变量是一个常量表达式,那就把他声明成 constexper,这样编译器会去严重变量的值是否是一个常量表达式

2.4.4 constexpr 和 常量表达式

  • 字面值类型:算术类型、引用、指针
  • constexper 指针的初始值必须是 nullptr 或 0,或是存在某个固定地址中的对象(函数体内无固定地址,所有函数外固定)
  • constexper 声明中定义了指针,你们那么 constexper 只对指针有效,与指针所指对象无关
  • constexpr 指针既可以指向常量也可指向非常量

2.5 处理类型

2.5.1 类型别名

  • 关键字 typedef 和 using 别名声明
  • 如果类型别名指代复合类型,要谨慎写,不要直接当作define去替换,要把别名当作一个整体来看待

2.5.2 auto 类型说明符

  • auto 让编译器通过初始值来推断类型,因此 auto 定义的变量必须有初始值
  • 使用 auto 在一条语句里声明多个变量,他们的基本类型(&和*只是声明符的一部分,而不属于基本类型)要相同。
  • 当引用被作为初始值的时候,编译器以引用对象的类型作为 auto 的类型,如果要推断为引用的话需要明确指出
  • auto 一般会忽略 顶层 const,如果不想忽略那么要明确指出

2.5.3 decltype 类型指示符

  • decltype 选择并返回操作数的数据类型
  • 如果 decltype 使用的表达式是一个变量,那么返回变量类型(包括顶层const和引用)
  • 如果 decltype 使用的表达式不是变量,那么返回表达式结果的类型
  • 引用和对象是同义词,不过在 decltype 这我们特殊区分
  • 如果 decltype 使用的表达式是解引用操作,那么返回得到引用类型
  • 对于 decltype 而言,变量加不加括号是不一样的,decltype((variable)) 返回永远是引用,decltype(variable) 只有当variable 本身是引用的时候才返回引用

2.6 自定义数据类型

  • 类内部定义的名字必须唯一,但是可以与类外部定义的名字重复
  • 类体右侧表示结束的花括号必须写一个分号,因为类体后面可以紧跟变量名
  • 每个对象有自己的一份数据成员的拷贝,修改一个对象的数据成员不会影响其他对象
  • 头文件一旦改变,相关的源文件必须重新编译获取更效过的声明
  • 类通常被定义在头文件当中,而且类所在头文件名字应该与类名字一样
  • 确保多文件多次包含仍能安全工作的技术是预
  • 预处理器(preprocessor),由C语言继承过来
  • C++ 还经常用到头文件保护符(header guard)
  • 预处理变量无视C++中关于作用域的规则

以上是关于C++ Primer 0x02 学习笔记的主要内容,如果未能解决你的问题,请参考以下文章

C++ Primer学习笔记

C++ primer puls 学习笔记

C++ Primer学习笔记

C++ Primer 0x06 学习笔记

C++ Primer 0x05 学习笔记

C++ Primer 0x10 学习笔记