复习C++小结(一)

nullptr

C++11中新加入了nullptr来初始化空指针。nullptr是一种特殊类型的字面值,它可以被转换成任意其他类型的指针。现在应当尽量使用nullptr而不是NULL来初始化空指针。

	int *a = nullptr;
	char *c = nullptr;

变量的声明与定义

变量能且只能被定义一次,但可以被多次声明。

extern double pi = 3.14; // 定义
int main(void)
{
	extern int a; // 声明	
	int b; // 定义
	extern double f = 0.01; // 错误:不允许对外部变量的局部声明使用初始值设定项(初始化)
}

关于引用

引用本身不是一个对象,定义引用时必须初始化,并且一旦定义后就无法改变其指向。

	int a = 0;
	int b = 1;
	int &ref = a;
	ref = b; // 该语句其实等价于a=b,并非将ref改成b的引用,引用一旦定义就无法改变其指向。

指向常量的指针和指针常量

代码中cptr是指向const double类型的指针即指向常量的指针。所以*cptr不能更改,但cptr本身可以更改,由于pi是并非const double,所以直接更改pi也是合法的。

	double pi = 3.14;
	const double *cptr = π
	pi = 3.1; // 合法
	cptr = 0; // 合法
	*cptr = 0; // 非法

代码中pip是指向const double类型的const指针,即指向常量的指针常量。pip本身和*pip都是不可修改的。而currErr是指针常量,不能修改currErr但能修改currErr所指向的errNumb的值。

	int errNumb = 0;
	int *const currErr = &errNumb;
	const double pi = 3.14;
	const double *const pip = π

constexpr常量表达式

C++11规定,允许将变量声明为constexpr类型以便由编译器来验证变量的值是否是常量表达式。声明为constexpr的变量一定是一个常量,而且必须用常量表达式初始化:

	constexpr int mf = 20;
	constexpr int limit = mf + 1;
	constexpr int sz = size(); // 非法,只有当size()是一个constexpr函数时正确。

在constexpr声明中如果定义了一个指针,限定符constexpr仅对指针有效,与指针所指的对象无关。
这段代码中p和q的类型相差甚远,p是一个指向常量的指针,q是一个指针常量。

	const int *p = nullptr;
	constexpr int *q = nullptr;

用constexpr修饰的指针指向的变量的地址必须是常量,比如放置在全局存储区的const int i,如果将const int i = 0这句话放在函数体内部就会报错,因为i的地址实在栈上的,会发生变化,p的值也就无法成为常量表达式了。

const int i = 0;
int main(void)
{
	constexpr const int *p = &i;
}

类型别名

C++11中有一种给类型取别名的新方法using。wages和wages2和double是等价的。

	typedef double wages;
	using wages2 = double;
	wages d1;
	wages2 d2;

需要特别注意的是以下这种情况,cstr和cstr2的数据类型并不相同,cstr2是指向const char对象的指针,而cstr却是指向char对象的指针常量。应当把pstring看作一个整体处理而非把他的别名替换回去处理。

	typedef char  *pstring;
	const pstring cstr = 0;
	const pstring *ps;

	const char *cstr2 = 0;

decltype

decltype通过推断表达式值的类型来推断要定义的变量类型,需要特别注意的是下面代码中*p对应的是int&型而非int型。

	const int ci = 0, &cj = ci;
	decltype(ci) x = 0;
	decltype(cj) y = x;
	decltype(cj) z; //错误:z是一个引用,必须初始化

	int i = 42, *p = &i, &r = i;
	decltype(r + 0) b; //正确,b是int类型
	decltype(*p) c; // 错误,*p是解引用,其得到的数据类型是引用型,必须初始化。可以理解为*p是i的别名,所以*p也是引用类型。
	auto d = *p; // 正确,d是int型,要和上面的区分开来。
	decltype((i)) e; // 错误,(i)会让编译器认为是一个表达式,因此是int&类型,必须初始化。
发布了6 篇原创文章 · 获赞 0 · 访问量 92

猜你喜欢

转载自blog.csdn.net/qq_33584870/article/details/104650887