原创
【博客大赛】《C++ Primer》学习笔记(十三)操作符和操作数
到这里,前三章的内容就学习完成了。
现在我们已经知道了怎么创建C++程序、怎么使用变量和修饰符、怎么使用strings和vector。
接下来该学习操作符和操作数了。
对于接触过C语言的人来说,操作符和操作数并不陌生。
但是它们对于C++的意义不止与此,其中一个很重要的概念就是操作符重载。
每一个表达式,要么是rvalue,要么是lvalue。
一般来说,我们使用rvalue时,使用的是它的值;使用lvalue时,使用的是它的地址。
之前学习过的decltype,括号内是变量还是表达式就有区别:
decltype((i))
decltype(a = b)
decltype(i)
当我们使用一个表达式来作为decltype的参数时,它返回的是lvalue的引用。
所以decltype((i))返回的是int&,decltype(a = b)返回的是int&。
如果p是一个int*的指针,则decltype(*p)返回的是int&。
如果p是一个int*的指针,则decltype(&p)返回的是int**。
另外,这本书里有个bug:
6 + 3 * 4 / 2 + 2
值是14,不是20!!!
这里我们并不知道这两个函数哪个先被执行:
int i = f1() * f2();
所以这两个函数的执行就不要有相互依赖的关系了,否则执行的结果是不确定的。
----------------
有关商和余数的符号问题……
以后在实际应用的时候慢慢调试吧。
----------------
不要使用true或者false来对一个操作数做比较,比如:
int val = /* ? */;
if (val == true)
cout << val << endl;
这是因为true会被转换成val的类型,此类型之间的比较可能会偏离程序本来的意图。
----------------
尽可能的使用++i,而不是i++。
用惯C语言的人可能很奇怪,为什么要这样做。这是因为后者会产生一个temp,从而需要更多步骤。
尤其在对迭代器进行操作的情况下,耗费的资源更多。因此还是尽量使用prefix。
----------------
sizeof操作符会返回以字节为单位的大小,数据类型是size_t。
sizeof (type)
sizeof expr
前者返回数据类型的大小,后者返回表达式的大小。
Sales_data data, *p;
int ia[10];
sizeof(Sales_data); //Sales_data所需空间大小
sizeof data; //Sales_data所需空间大小
sizeof p; //指针的大小
sizeof *p; //Sales_data所需空间大小
sizeof data.revenue; //Sales_data的成员revenue所需空间大小
sizeof Sales_data::revenue; //同上
sizeof ia; //数组大小,不是指针大小
sizeof返回的是个常量:
constexpr size_t sz = sizeof(ia) / sizeof(*ia);
int arr2[sz];
----------------
隐式类型转换的时候会发生什么?
• 大部分的表达式里,小于int的类型会被转换成int;
• 在条件判断里,非boot的表达式会被转换成bool;
• 初始化的时候,初始值会被转换成变量类型,赋值时右操作数会被转换成左操作数;
• 在算术和关系运算中,混合的操作数会被转换成common类型;
• 函数调用时也会发生自动类型转换。
显式类型转换的时候会发生什么?
static_cast
它经常用在使用大的数据类型给小的数据类型赋值时,它告诉程序员和编译器,精度的损失无关紧要。
如果不使用它,编译器可能会发生警告;使用它,则声明警告是已知的。
double slope = static_cast<double>(j) / i;
void *p = &d;
double *dp = static_cast<double*>(p);
const_cast
它可以把被const修饰的对象转换成非const的,实际上也只有它可以。
虽然编译器会允许我们往这样的变量里写入,但是会发生什么是不确定的。
const char *cp;
char *q = static_cast<char*>(cp);
static_cast<string>(cp); //正确,static_cast可以用来进行类型转换
const_cast<string>(cp); //错误,const_cast只能用来转换const
reinterpret_cast
它可以重新对对象进行解释。
int *ip;
char *pc = reinterpret_cast<char*>(ip);
实际的对象仍然是int,因此把它当char使用语法没问题,但是功能有问题。这也说明它是非常危险的。
所以除非我们确信需要,并且明白它干了什么,否则就不要使用它了。
dynamic_cast
以后再解释。
----------------
第四章的内容,有关操作符和操作数到这里就学习完毕。
它有很多和C语言重复的内容,所以可能会看得非常无聊!
Anyway,实际使用的时候还会回过头来进行练习。现在进行下一章吧。
DiracFatCat 2016-3-19 13:11
东莞元宝代理Microchip长电二三极管 2016-3-18 08:16