C++ Primer 5th读书笔记(一)变量和基本类型
变量和基本类型
列表初始化
C++语言定义了初始化的好几种不同形式,很常见的一种形式就是:
int s = 0;
其实还有如下三种形式:
int s1 = {0}; int s2{0}; int s3(0);
这里有个概念需要辨析:初始化 != 赋值。初始化是指创建变量时赋予其一个初始值,而赋值是指把对象的当前值擦出,用一个新值来代替。
在C++11新标准中,用花括号初始化变量得到了全面应用,这种形式被称为列表初始化(list initialization)。当其用于内置类型的变量时,如果初始值存在信息丢失的风险,编译器会报错。采用QT5+MinGW4.8编译运行书中的例子不至于报错,但是提示warning了,所以还是要注意避免。
long double ld = 3.1415926536; int a{ld}, b = {ld}; //wrong int c(ld),d=ld; //correct
const限定符
最常见的用途就是对变量进行限定,使初始值不能改变。现在在c++程序中如果要定义使用常量,也都推荐用const,而非以前的#define。由于const对象创建后,值就无法再改变,因此const对象必须初始化。
(1) const的引用
可以把引用绑定到const对象上,称之为对常量的引用(reference to const),或者简称常量引用。对常量的引用不能被用作修改其所绑定的对象,但是允许为一个常量引用绑定非常量的对象、字面值。Primer书中的例子很明了,如下:
int i = 42; int &r1 = i; const int &r2 = i; //r2绑定对象i,但是不允许通过r2修改i的值 cout << "i:"<<i<<endl; cout << "r1:"<<r1<<endl; cout << "r2:"<<r2<<endl; r1 = 0; cout << "i:"<<i<<endl; cout << "r1:"<<r1<<endl; cout << "r2:"<<r2<<endl;
输出结果:
(2)指针和const
类似于常量引用,指向常量的指针(pointer to const)不能用于改变其所指对象的值。要想存放常量对象的地址,只能使用指向常量的指针。运行下书中给的小例子就能立刻明白这两句话的意思了。
const double pi = 3.1415; const double *cptr = π cout << "cptr points to:"<< * cptr <<endl; //*cptr = 42; //wrong1 //double *ptr = π //wrong2 double d = 1.2345; cptr = &d; cout << "cptr points to:"<< * cptr <<endl;
输出结果:
指针是对象,因此可以把指针本身定义为常量,把*放在const之前用以说明指针是一个常量,这样表明不变的是指针本身而不是指针指向的那个值。就以刚刚的例子说明,稍稍把cptr的定义做个修改
const double *const cptr = π //cptr是一个指向常量对象的常量指针
重新编译就会发现 cptr=&d; 这句话报错了
由此例可知指针本身以及其所指对象是否为常量是相互独立的问题。Primer书中给了俩个定义,顶层const表示指针本身是个常量;底层const表示指针所指对象是一个常量。另外书中还提供理解复杂声明含义的小技巧——从右向左阅读。如上例,离cptr最近的是const,所以cptr本身是一个常量对象,其类型有声明符的其余部分确定。下一个符号是*,故cptr是一个常量指针。声明语句的基本数据类型部分确定了常量指针指向的是一个double常量对象。
constexpr
常量表达式是指值不会改变并且在编译过程就能得到计算结果的表达式。C++11允许讲变量声明为constexpr类型以便由编译器来验证变量的值是否为一个常量表达式。以下是书中的例子。
constexpr int mf = 20; //20是常量表达式 constexpr int limit = mf + 1; //mf +1是常量表达式 constexpr int sz = size(); //只有当size是一个constexpr函数时才是一条正确的声明语句
另外还需注意的是,如果constexpr声明中定义了指针,constexpr只对指针有效,与指针所指对象无关,即constexpr把它定义的对象置为了顶层const。
posted on 2013-11-28 12:46 woolongtea 阅读(511) 评论(2) 编辑 收藏 举报