习惯上,头文件根据其中定义的类的名字来命。 char16_t表示16位的Unicode字符,char32_t表示32位的Unicode字符。 类型unsigned int可以缩写位unsigned。 当一个算术表达式中既有无符号数,又有int值时,int值会被转化为无符号数。无符号数运算后得到的结果一定是正数。 u前缀表示char16_t类型的Unicode字符,U前缀表示char32_t类型的Unicode字符。L前缀表示wchar_t类型的宽字符,u8前缀表示char类型的utf-8字符。 u或U后缀的表示无符号数,f或F表示float类型,l或L表示long类型,ll或LL表示long long类型 C++新特性,列表初始化(list initalization)
int units_sold = 0;
int units_sold{0};
//但是列表初始化存在丢失信息的风险
long double ld = 3.1415
int a{ld}, b = {ld};
int c{ld}, d = ld;
//使用long double初始化int类型变量会产生丢失信息,因此,对a,b的初始化会报错
如果定义的变量没有被初始化,那么会依据所定义的类型产生默认初始化。定义在函数体内部的内置类型变量将不被初始化,除非函数得到调用。 如果想声明一个变量而不是定义它,使用extern关键字
extern int i;//声明而非定义i
int j;//声明并定义j
//如果使用关键字extern是赋值,则声明的同时定义了该变量
extern double d = 3.1415;//声明并定义变量d
下划线_可以作为变量名 变量的作用域能彼此包含,内部重复定义的变量将覆盖外层定义变量,使用作用域操作符可以访问全局变量
int i = 100;
int main()
{
int i = 30;
cout << i << endl;//输出i为30
cout << ::i << endl;//输出i为100
return 0;
}
引用必须被初始化,通过声明符写成&d形式。引用只能绑定在对象上,不能与字面值或者某个表达式的计算结果绑定,引用即别名。
int ival = 1025;
int &r = 10;//错误的用法
int &refVal = ival;//refVal是指向ival的引用(是ival的另一个名字)
//意思是变量refVal是引用类型变量
指针通过声明符写成*d的形式。与引用类似,指针也实现了对对象的间接访问,但是两者有所差异。指针本身就是一个对象,允许对指针赋值和拷贝;指针不需要在定义的时候赋值。注意!在块作用域内定义的指针如果没有初始化,将会拥有一个不确定值。
int ival = 32;
int *p = &ival;//变量p存放变量ival的地址,即p是指向ival的指针
//变量p为int类型的指针,初始化令其指向名为ival的int变量
//由于引用不是对象,所以不能定义指向引用的指针
如果指针指向一个对象,那么允许使用解引用符(*)来访问该对象,对指针进行解引用操作会得到所指的对象,如果对解引用的结果赋值,也就是对指针所指的对象赋值。
int ival = 4;
int *pIval = &ival;
cout << pIval << " " <<*pIval << endl;
cout << &ival << " " << ival << endl;
*pIval = 10;
cout << ival <<" "<< &ival << " " << pIval << endl;
//对解引用后的结果赋值更改了原值,但是地址一直没有改变
//007BF7C8 4
//007BF7C8 4
//10 007BF7C8 007BF7C8
C++新特性中提供了nullptr来初始化空指针。nullptr是一个特殊的字面值,可以被转换成任意其他的指针类型。建议初始化所有指针,不清楚指向谁时,初始化为nullptr或0。 void*是一种特殊类型的指针,可以存放任意对象的地址。但不能直接操作void*所指的对象。 指向指针的指针**pptr,指向指针的引用*&r
int ival = 1024;
int *ptr = &ival;//ptr是一个指向int类型的指针
int **pptr = &ptr;//pptr是一个指向int指针类型的指针
//pptr -> ptr -> ival(1024)
int i = 42;
int *p = &i;
int *&r = p;//r是一个对指针p的引用
//p(r) -> i(42)
const限定符,const对象一旦创建之后其值就不能再被改变,所以const对象必须初始化。默认情况下,const对象被设定为文件内有效,当多个文件中都出现了同名的const变量时,其实等同于再不同文件中分别定义了独立的变量。注意!!有时候需要共用一个值时,不希望编译器为每个文件分别产生独立的变量,这时就可以使用关键字extern
//file_1.cc定义并初始化了一个常量,该常量可以被其他文件访问
//.cc表示Linux/Unix下为C++源文件的默认扩展名,与.cpp一个意思
extern const int bufSize = fcn();
//file_1.h头文件
extern const int bufSize;//与file_1.cc中定义的bufSize为同一个
//头文件中的声明使用extern做了限定,指出bufSize并非本文件所独有
对常量的引用不能修改其绑定的对象。但是对const的引用可以绑定任意表达式,只要该表达式能转化为任意引用的类型即可。
int i = 42;
const int &r1 = i;//正确
const int &r2 = 1024;//正确
int &r3 = 512;//错误
//对const的引用为非const对象时,不能通过const引用去更改非const对象
int i = 42;
int &r1 = i;
const int &r2 = i;
r1 = 0;//正确
r2 = 0;//错误
要想存放常量对象的地址,需要定义指向常量的指针(底层const)。
const double pi = 3.14;
double *ptr = π//错误用法,ptr只是一个普通指针
const double *cptr = π//正确用法,cptr是一个指向双精度常量的指针
*cptr = 42;//错误用法,不能更改常量值
常量指针(const指针)指的是该指针一直指向某个对象,而不会改变(顶层const),所指向对象的内容可以改变。定义时将(*)写在const前
int numErr = 0;
int *const cptr = &numErr;//cptr指针会一直指向numErr
const double pi = 3.1415;
const double *cppi = π//这是一个指向常量的普通指针
const double *const ccpi = π//这是一个指向常量的常量指针,会一直指向pi
常量表达式,指的是在程序编译过程中就能得到计算结果的表达式。constexpr变量,新标准中允许将变量声明为constexpr类型,可以由编译器来验证变量的值是否为一个常量表达式。
cosntexpr int mf = 20;//20是常量表达式
constexpr int limit = mf + 20;//mf+20是常量表达式
constexpr int sz = size();//只有当size()是一个constexpr函数时,才是一条正确语句
auto类型,当表达式的值的类型不确定时,使用auto类型声明由编译器判定
auto item = val1 + val2;//item初始化的结果为val1和val2的和
auto i = 0, *p = &i;//正确操作,i是整型,p为指向整型的指针
auto sz = 0, pi = 3.14;//错误操作,sz和pi类型不一致
decltype类型,当需要推断出返回值的类型,而不需要计算出返回的结果时,使用该关键字。(c++11新标准)
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;//错误,z为引用,必须初始化
//注意
int i = 43, *p = &i;
decltype(*p) c;//错误操作,decltype(*p)得到的时int&类型,引用必须初始化