C++ Primer Plus 读书笔记(第3章)
第三章 处理数据
今天完成了该章的阅读, 本章对C++涉及的数据类型做了一个详尽的说明, 并且对于C++与C的细微区别做了说明, 总的来所就是C++兼容C的习惯, 但是作者告诉我们为什么C++要做出这些改变, 细细想想, 的却是有道理.该章中牵涉到了部分C++11特性, 所以要确保编译器支持这些特性, 本人使用dev 5.2.0.3. 在工具->编译选项->编译器 标签下选择编译时加入以下命令, 并在框中输入 -std=c++0x 即可.
最简单的使用计算机处理数据的思维过程
1.信息将存在哪里;
2.要存储说明值;
3.存储何种类型的信息.
大概的想法就是根据需求来安排合理的存储类型吧. 当然在这之前就是要了解各个类型的特性.
关于变量的命名
经典的那几条就不提了, 书中还添加了一条:
一两个下划线或下划线和大写字母打头的名称被保留给实现(编译器及其使用的资源)使用.以一个下划线开头的名称被保留给实现, 用作全局标示符.
对类型所占字节数的规定
short 至少16位;
int 至少与 short 一样长;
long 至少为32位, 且至少与 int 一样长;
long long 至少64位, 且至少与 long 一样长.
float 至少为32位;
double 至少为48位, 且至少与 float 一样长;
long double 至少与 double 一样长.
一种新的初始化
int var(5); // 新的初始化方式, 等价于 int var = 5; 之所以提供这种方式, 因为这样和初始化自己的类的形式非常相似.
对一个变量的初始化要及时.
short year;
year = 1492;
并不提倡这样的初始化, 因为在实际编码的过程中, 万一这两条语句是分开的话, 那么中间的时刻, 变量的值就一直是未定义的. 这大大加大了程序的风险.
C++11推荐使用花括号初始化器来初始化一个变量(又称列表初始化)
short year {1942} // 可以省略掉括号
short year {} // 省略的话, 将会初始化为0
还有一个作用就是防范类型转换错误, 具体地说, 列表初始化不允许窄缩(narrowing), 即变量的类型可能无法表示赋给它的值. 例如, 不允许将浮点型转化为整型, 在不同的整数之间转换或将整型转化为浮点型可能被允许, 条件是编译器知道目标变量能够正确的存储赋给它的值. 例如, 可将int型赋值给long, 因为long至少和int一样长; 相反方向的转换也可能被允许, 只要int变量能够存储赋给它的值.
选择整形类型
如果知道变量的值可能会大于16位整数, 那么建议使用long, 因为long规定了至少为32位, 而int可能在另外一台机器上只有16位.
如果确定数值不超过short范围, 且是大型整型数组时, 建议使用short, 因为大部分的机器上int都是32位. 否则占用内存就将加倍. 内存是能省则省.
整型字面值
以1-9开头的数字为十进制数;
以0开头的数字为八进制数;
以0x或者是0X开头的数字为十六进制数;
源字符集与执行字符集
源字符集:即可用来编写源代码的字符集.
执行字符集:即程序执行期间可处理的字符(如可从文件中读取或显示到屏幕上的字符)还增加了一些字符, 如退格和振铃.
C++允许对这两者进行扩充. 以后说不定可以 int 中国 = 0;
const和define的比较
define是C语言中常用的定义常量的方式. C++推荐使用const有下面三条原因:
1.它能够明确指定类型;
2.可以使用C++作用域规则将定义限制在特定的函数或文件中;
3.可以讲const用于更复杂的类型.
C++能够使用const变量来初始化数组长度, 而C语言是不允许的.
浮点数的一句话概括
浮点数就是一部分表示值, 一部分用于对值进行放大或缩小.
d.dddE+n 指的是将小数点向右移n位, 而d.dddE-n 是将小数点往左移n位. 之所以称之为”浮点”就是因为小数点可以移动.
浮点数的精度之痛
由于浮点数的精度是有限的因为一个很大的浮点数加上一个比较小的数的话, 那么这个浮点数看不到任何改变. 例如1e22 + 1, 这个数用float来表示和 1e22意义相同, 因为精度只有6位. 浮点数的运算速度较慢, 而且计算总是伴随着精度问题. 幸好的是平时的应用中对精度的要求并不高.
优先级及结合性
该本书的这一说明终于给我说明白了, 以前谭老的那本书说的总觉得不好理解.从左到右的结合性意味着如果两个优先级相同的运算符作用于同一个操作数, 则首先应用左侧的运算符. 直接举几个例子.
int flyingpigs = 3 + 4 * 5;
4到底和3做运算还是和5做运算, 由于* 优先级高于 +, 所以先作后面的运算
int logs = 120 / 4 * 5;
这个又稍微有点区别, 4到底是和120做运算还是和5做运算. 由于 / 和 * 的优先级相同,所以这个时候就要结合性, 查表可知结合性为从左至右, 因此4先和120结合. 所以最后的结果是150.
注意, 仅当两个运算符被作用于同一操作数时, 优先级和结合性规则才有效.
int dues = 20 * 5 + 24 * 6;
由优先级能够知道20 * 5 和 24 * 6一定是优先做的. 但是优先级和结合性都没有说明是先计算左边的乘号还是先计算右边的乘号, C++把这个问题留给了实现. 依赖于不同的编译平台.
C++11 中的auto声明
这个东西有有优点也有缺点, 问题就在于用在什么地方.首先它的作用是用来在不显式的知名数据类型的情况下, 编译器能够根据初始化的值来自动决定这个变量的类型.
auto n = 100; // n is int
auto x = 1.5; // n is double
auto y = 1.3e12L // y is long double
如果仅仅是这样使用的话, 很可能造成我们不愿意看到的错误:
double y = 0; // y is double, no problem, 0 automatically converted to 0.0
auto y = 0; // y is int, but you want to get a double y, just init by 0
后面的y并没有如愿以偿得到double型.
一个有用的使用方法是在使用迭代器的时候, 我们知道申请一个迭代器变量时需要长长的一串代码, 所以这个就非常好用了.
vector<double> scores;
auto it = scores.begin();
这样就能够轻松的得到一个迭代器了.