初始化(initialize):对象在创建时获得了一个特定的值。
- 初始化不是赋值:
- 初始化 = 创建变量 + 赋予初始值
- 赋值 = 擦除对象的当前值 + 用新值代替
- 列表初始化:使用花括号
{}
,如int units_sold{0};
orint units_sold={0}
- 默认初始化:定义时没有指定初始值会被默认初始化;在函数体内部的内置类型变量将不会被初始化。
- 在定义于函数体内的内置类型对象如果未被初始化,其值未定义;类的对象如果未被初始化,其值由类决定。
- 建议初始化每一个内置类型的变量。
引用
- 引用:引用是一个对象的别名,引用类型引用(refer to)另外一种类型。如
int &refVal = val;
。 - 引用必须初始化。
- 引用即是给一个已经存在的对象起一个别名(以后refVal代表val)
- 引用不是一个对象,所以不能定义引用的引用
- 引用类型必须相同
- 引用和它的初始值是绑定bind在一起的,而不是拷贝。
假设 p 是一个 int 型指针,请说明下述代码的含义。
int *p;
if (p) // ...
if (*p) // ...
解:
第一句判断 p 是不是一个空指针(是否有地址值), 第二句判断 p 所指向的对象的值是不是为0
指针
-
指针本身是一个对象,它又可以指向另外一个对象。
-
是
"指向(point to)"
另外一种类型的复合类型。 -
定义指针类型:
int *ip1;
,从右向左读,ip1
是指向int
类型的指针。而
int ip1
,ip1是int型对象 -
指针存放某个对象的地址。
-
获取对象的地址:
int i=42; int *p = &i;
。p存放着int
类型变量i的地址,或者说p是指向int
类型变量i的指针。&
是取地址符。 -
指针的值的四种状态:
- 1.指向一个对象;
- 2.指向紧邻对象的下一个位置;
- 3.空指针;
- 4.无效指针。
-
指针访问对象:
cout << *p;
,*
是解引用符。 -
空指针不指向任何对象。
-
空指针用字面值
nullptr
来定义 -
int *p=nullptr;
orint *p=0
-
#include <cstdlib.h> int *p=NULL;
-
void*
指针可以存放任意对象的地址。 -
其他指针类型必须要与所指对象严格匹配。
-
两个指针相减的类型是
ptrdiff_t
。 -
建议:初始化所有指针。
const限定符
- 定义:定义一些不能被改变值的变量。
初始化和const
- const对象必须初始化,且不能被改变。
- const变量默认不能被其他文件访问,非要访问,必须在指定const前加extern。
const的引用
- reference to const(对常量的引用):指向const对象(不能修改它所绑定的对象)的引用,如
const int ival=1; const int &refVal = ival;
,可以读取但不能修改refVal
。 - 如果左边是非常量,右边是常量,则不能使它们引用成功,即引用(绑定)不能是非常量(除非要绑定的对象是非常量,此时该引用还是非常量),而常量引用可以绑定到一个普通int对象上,也可以绑定到一个常量对象上
- 临时量(temporary)对象:当编译器需要一个空间来暂存表达式的求值结果时,临时创建的一个未命名的对象。
- 对临时量的引用行为非法。
指针和const
- pointer to const(指向常量的指针):不能用于改变其所指对象的值,但是可以改变该指针自己存放常量对象的地址 如
const double pi = 3.14; const double *cptr = π
。 - 想要存放常量对象的地址,必须使用指针常量,即左边要是底层const(指针常量是底层啦~),而右边是顶层const,这跟引用的要求一样,必须两边都是顶层const
- 指针常量仅仅要求不能通过该指针改变对象的值,而没有规定那个对象的值不能通过其他途径改变
- const pointer:指针本身是常量,如
int i = 0; int *const ptr = &i;
- 常量指针必须初始化,初始化完成后,其值(即存放在指针中的那个地址)就不能改变了,不变的是指针本身的值而不是指向的那个对象值
*
在const前为常量指针(重点是指针本身是一个常量)*
在const后为指针常量(重点是该常量对象本身是一个常量)
顶层const
顶层const
:指针本身是个常量。底层const
:指针指向的对象是个常量。拷贝时严格要求相同的底层const资格。- 用于声明引用的const都是底层const
- 拷贝操作不会影响对象的值,对是否是常量没有影响
constexpr
和常量表达式
- 常量表达式:指值不会改变,且在编译过程中就能得到计算结果的表达式。
C++11
新标准规定,允许将变量声明为constexpr
类型以便由编译器来验证变量的值是否是一个常量的表达式。
自定义数据结构
struct
- 类可以以关键字
struct
开始,紧跟类名和类体。 - 类体定义类的成员,我们的类只有数据成员。
C++11
:可以为类数据成员提供一个类内初始值(in-class initializer)。
编写自己的头文件
- 头文件通常包含哪些只能被定义一次的实体:类、
const
和constexpr
变量。
预处理器概述:
- 预处理器(preprocessor):确保头文件多次包含仍能安全工作。
- 当预处理器看到
#include
标记时,会用指定的头文件内容代替#include
- 头文件保护符(header guard):头文件保护符依赖于预处理变量,有两种状态:已定义和未定义。