指针字面值
变量定义
- 定义形式:类型说明符(type specifier) + 一个或多个变量名组成的列表。如int sum = 0, value, units_sold = 0;
- 初始化:对象在创建时获得了一个特定的值
- 初始化不是赋值
- 初始化 = 创建变量 + 赋予初始值
- 赋值 = 擦除对象的当前值 + 用新值代替
- 列表初始化:使用花括号{},如int units_sold{0};
- 默认初始化:定义时没有指定初始值会被默认初始化;在函数体内部的内置类型变量将不会被初始化。
- 建议初始化每一个内置类型的变量。
变量声明和定义
- 只声明而不定义: 在变量名前添加关键字 extern,如extern int i;。但如果包含了初始值,就变成了定义:extern double pi = 3.14;
- 变量只能被定义一次,但是可以多次声明。
复合类型
引用(指的是左值引用) 右值引用见chapter13,主要用于内置类
- 引用:引用是一个对象的别名,引用类型引用(refer to)另外一种类型。如int &refVal = val
- 引用必须初始化。
- 引用和它的初始值是绑定在一起的,而不是拷贝。
指针
- 空指针 int *p1 = nullptr(c++11) 或 int *p2 = 0
或者首先#include cstdlib 再 int *p3 = NULL
- 指向指针的引用 :引用本身不是一个对象,所以不能定义指向引用的指针。但指针是对象,所以存在对指针的引用。
int i = 42;
int *p;
int *&r = p;
r = &i;
*r = 0;
const限定符
初始化和const
const int i = get_size()
const int j = 42;
const int k;
- 默认状态下,const对象只在文件内有效
以编译初始化方式定义一个const对象时,const int bufSize = 512;编译器将在编译过程中把用到该变量的地方都替换成对应的值。
- 多个文件之间共享const对象,须在变量定义之前添加extern关键字
extern const int bufSize = fcn();
extern const int bufSize;
const引用(对常量的引用)
const int ci = 1024;
const int &r1 = ci;
r1 = 42;
int &r2 = ci;
int i = 42;
const int &r1 = i;
cosnt int &r2 = 42;
const int &r3 = r1*2;
int &r4 = r1*2;
int i = 42;
int &r1 = i;
const int &r2 = i;
r1 = 0;
r2 = 0;
指针和const(存放常量对象的地址,只能使用指向常量的指针)
const double pi = 3.14;
double *ptr = π
const double *cptr = π
*cptr = 42;
- 与常量引用其引用对象是非常量相同,指向常量的指针也可指向非常量,只是"自以为是“的觉得自己指向了常量,所以自觉地不去改变所指对象的值。
const指针
int errNumb = 0;
int *const curErr = &errNumb;
const double pi = 3.14;
const double *const pip = π
顶层const(指针本身是常量)和底层const(指向对象是常量)
- 拷贝时严格要求相同的底层const资格。注意两点:(1)int* 能转换成const int* (2)const int&可以绑定到一个普通int上
constexpr和常量表达式
- 常量表达式指值不会改变并且编译过程就能得到计算结果的表达式。
const int max_files = 20;
const int limit = max_files + 1;
int staff_size = 27;
const int sz = get_size();
- constexpr变量:允许将变量声明为constexpr类型以便由编译器来验证变量的值是否是一个常量表达式,声明为constexpr的变量一定是一个常量,且必须用常量表达式初始化:
constexpr int mf = 20;
constexpr int limit = mf + 1;
constexpr int sz = size()
- 普通函数不能作为constexpr的初始值。若你认定变量是一个常量表达式,就把它声明成constexpr类型。
const int *p = nullptr;
constexpr int *q = nullptr;
处理类型
类型别名
typedef double wages;
typedef wages base,*p;
using SI = Sales_item;
SI item;
指针,常量和类型别名
typedef char *pstring;
const pstring cstr = 0;
const pstring *ps;
auto类型说明符
auto item = val1 + val2;
auto i = 0,*p = &i;
auto sz = 0,pi = 3.14;
- 会忽略掉顶层const,同时底层const则会保留下来。
const int ci = i,&cr = ci;
auto b = ci;
auto c = cr;
auto d = &i;
auto e = &ci;
- 若希望推断出的auto类型是一个顶层const,需明确指出:
const auto f = ci;
auto &g = ci;
auto &h = 42;
const auto &j = 42;
- decltype类型指示符(从表达式的类型推断出要定义的变量的类型,选择并返回操作数的数据类型)
decltype(f()) sum = x;
const int ci = 0,&cj = ci;
decltype(ci) x = 0;
decltype(cj) y = x;
decltype(cj) z;
int i = 42,*p = &i,&r = i;
decltype(r+0) b;
decltype(*p) c;
decltype((i)) d;
decltype(i) e;
编写自己的头文件
- 头文件通常包含哪些只能被定义一次的实体:类、const和constexpr变量。
- 预处理器(preprocessor):确保头文件多次包含仍能安全工作。
- 当预处理器看到#include标记时,会用指定的头文件内容代替#include
- 头文件保护符(header guard):头文件保护符依赖于预处理变量的状态:已定义和未定义。
#ifndef SALES_DATA_H
#define SALES_DATA_H
#include <string>
struct Sales_data{
std::string bookNo;
unsigned units_sold = 0;
double revenue = 0.0;
};
#endif