//file_1.cc定义并初始化一个常量,该常量能够被其他文件访问
extern const int bufSize=fcn();
//file_1.h头文件
extern const int bufsize;//与file_1.cc中定义的bufsize是同一个
const的引用
对常量的引用:将引用绑定到const对象上
const int ci=1024;
const int &r1=ci;//正确:引用及其对应的对象均为常量
//r1 = 42;错误
//int &r2=ci;错误
初始化和对const的引用
引用的类型必须与其引用对象的类型一致的例外
初始化常量引用时运行用任意表达式作为初始值
运行为一个常量引用绑定非常量的对象、字面值或表达式
int i=0;
const int &r1=i;
const int &r2=42;
const int &r3=r1*2;
//int &r4 = r1*2;错误,r4为普通的非常量引用
指针和const
指向常量的指针不能用于改变其所指对象的值
指针的类型必须与其所指对象的类型一致的例外
允许将一个指向常量的指针指向一个非常量对象
double a=3.14;
const double *cptr=&a;
顶底层const
顶层const:指针本身为一个常量
底层const:指针所指的对象时一个常量
int i=0;
int *const p1=&i;//不能改变p1的值,为顶层const
const int ci=42;//不能改变ci的值,为顶层const
const int *p2=&ci;//允许改变p2的值,不允许改变ci的值,为底层const
constexpr和常量表达式
常量表达式:其值不会改变并且在编译过程就可得到计算结果的表达式
const int a=10;//true
const int b=a+1;//true
int c=10;//false
int d=c+1;//false
int e=func();//false
constexpr变量
将变量声明为constexpr类型以便编译器验证变量的值是否为一个常量表达式
constexpr int a=10;//true
constexpr int b=a+1;//true
constexpr int sz=func();//只有当func时一个constexpr函数时才是一条正确的声明语句
constexpr只对指针有效,与指针所指对象无关
const int *p=nullptr;//p是一个指向整型常量的指针
constexpr int *q=nullptr;//q是一个指向整数的常量指针
处理类型
类型别名
使用关键字typedef
typedef double wages;
typedef wages base,*p;
使用别名声明
using SI=int;
auto类型说明符
由编译器通过初始值推算变量的类型
auto可在一条语句中声明多个变量,该语句中所有变量的初始基本数据类型必须一样
auto i=0,*p=&i;
//auto sz=0,pi=3.14;
auto一般会忽略顶层const,底层const会保留夏哩
int i=0,&r=i;
auto a=r;//a是一个整数
const int ci=i,&cr=ci;
auto b=ci;//b是一个整数,ci的顶层const被忽略
auto c = cr;//c是一个整数
auto d = &i;//d是一个整型指针
auto e = &ci;//e是一个整向整数常量的指针
decltype类型指示符
选择并返回操作数的数据类型
从表达式的类型推断出要定义的变量的类型,但不使用该表达式的值初始化变量
decltype(f())sum=x;//sum的类型为函数f的返回类型
const int ci=0,&cj=ci;
decltype(ci)x=0;//x的类型为const int
decltype(cj)y=x;//y的类型为const int&
//decltype(cj)z;
decltype和引用
如果decltype使用的表达式不是一个变量,则decltype返回表达式结果对应的类型
如果表达式的内容是解引用操作,则decltype将得到引用类型
int i=42,*p=&i;&r=i;
decltype(r+0)b;//b是一个未初始化的int
decltype(*p)c;//c是int&,必须初始化