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 学习笔记的主要内容,如果未能解决你的问题,请参考以下文章