title: 第二章——变量和基本类型
date: 2022-04-29 16:27:20
tags:
- C++ Primer
mathjax: true
第二章——变量和基本类型
对象
-
对象是指:一块能存储数据并具有某种类型的内存空间
-
对象是具有某种数据类型的内存空间。
-
对象的类型决定了其上的操作。
变量命名规范
- 标识符要能体现实际含义
- 变量名一般用小写字母,如 index,不要用 Index 或 INDEX
- 用户自定义类名一般以大写字母开头,如 Sales_item
- 如果标识符由多个单词组成,则单词间应有明显区分,如 student_loan 或 studentLoan,不要用studentloan
变量定义的时机
- 一般来说,在对象第一次被使用的地方附近定义它是一种好的选择,这样做有助于更容易的找到变量的定义。更重要的是,当变量的定义与它第一次被使用的地方很近时,我们会赋给它一个比较合理的初始值。
复合类型
-
指针(初始化所有指针)
//空指针的定义: int *p1 = nullptr; // 等价于 int *p1 = 0; 这种方法最简单。最好使用这种。C11标准。 int *p2 = 0; // 直接将 p2 初始化为字面常量 0 // 需要首先#include cstdlib int *p3 = NULL; // 等价于 int *p3 = 0;
-
引用
P56 和 P534 页 两种例外
除了两种例外情况外,其他所有引用的类型都要和与之绑定的对象严格匹配。
- 第一种例外就是,在初始化常量引用时允许用任意表达式作为初始值。(P56)
- ?
除了两种例外情况外,其他所有指针的类型都要和其指向的对象严格匹配。
- 第一种例外就是,允许令一个指向常量的指针指向一个非常量的对象。
const对象仅在文件内有效
- 默认情况下,const对象被设定为仅在文件内有效。当多个文件中出现了同名的const的变量时,其实等同于在不同文件中分别定义了独立的变量。
- 有些时候有这样一种 const 变量,它的初始值不是一个常量表达式,但又确实又必要在文件间共享。这种情况下,我们不希望编译器为每个文件分别生成独立的变量。相反,我们想让这类 const 对象像其他(非常量)对象一样工作,也就是说,只在一个文件中定义 const ,而在其他多个文件中声明并使用它。
解决方法是:对于const变量不管是声明还是定义都添加 extern 关键字,这样只需要定义一次就行了。
引用 与 const
-
要想绑定const对象,只能使用常量引用。
-
常量引用是对 const引用。
-
初始化和对 const 的引用
double dval = 3.14; const int &ri = dval; //执行这两条语句到底发生了什么? //发生了以下变化,编译器会把上述代码变成了如下形式: const int temp = dval; //有双精度浮点数生成一个临时的整型变量 const int &ri = temp; //让 ri 绑定这个临时量 //这种情况下, ri 绑定了一个临时量对象。
-
对 const 的引用可能引用一个并非 const 的对象
此时,引用是 const ,但引用绑定的值是非 const 对象。不能通过引用改变对象的值,但是并不影响对象通过其他操作改变自己的值。
指针 与 const
-
要想存放const对象的地址,只能使用指向常量的指针。
-
指针与引用不同,指针是对象而引用不是,因此就像其他对象一样,允许把指针本身定为常量。__常量指针__必须初始化,而且一旦初始化完成,则它的值就不能再改变了。
-
也就是说,因为指针是对象,所以有了两种情况:
- 常量指针:指针的指向不能变
- 指向常量的指针:不能通过指针改变对象(这个对象可以是常量也可是非常量)的值。
-
顶层const表示指针本身是一个常量,底层const表示指针所指的对象是一个常量。
常量表达式
-
是指,不会改变并 且 在编译过程中就能得到计算结果的表达式。
-
constexpr 常量,声明为 constexpr 的变量一定是一个常量,而且必须用常量表达式初始化:
constexpr int mf = 20; //20是常量表达式 constexpr int limit = mf + 1; // mf + 1 是常量表达式 constexpr int sz = size(); //只有当 size 是一个constexpr函数时,才是一条正确的声明语句。
-
必须指明一点,,在constexpr声明中如果定义了一个指针,限定符 constexpr 仅对指针有效,与指针所指的对象无关。
const int *p = nullptr; //p是一个指向整型常量的指针 constexpr int *q = nullptr; //q是一个指向整数的常量指针
q 和 p 相差甚远,p 是一个指向常量的指针,q 是一个常量指针。
类型别名
-
指针、常量和类型别名
typedef char *pstring; const pstring cstr = 0; //cstr是指向char的常量指针 const pstring *ps; //ps是一个指针,它的对象是指向 char 的常量指针
const 是对给定类型的修饰。pstring 实际上是指向 char 的指针,因此,const pstring 就是指向 char 的常量指针,而非指向常量字符的指针。
-
auto 类型说明符
编程是常常需要把表达式的值赋给变量,这就要求在声明变量的时候清楚的知道表达式的类型。然而要做到这一点并非那么容易。
为了解决这个问题,C++11 新标准引入了 auto 类型说明符,用它就能让编译器替我们去分析表达式所属的类型。
显然,auto定义的变量必须有初始值。
-
decltype 类型指示符
有时会遇到这种情况:希望从表达式的类型推断出要定义的变量类型,但是不想用该表达式的值初始化变量。
decltype(f()) sum = x; //sum的类型就是函数 f 的返回类型
需要指出的是,引用从来都作为其所指对象的同义词出现,只有用在decltype处是一个例外。