第二章
1.
c++支持分离式编译,可以将声明和定义区分开,声明使得名字为程序所知,定义是创建一个与名字关联的实体。
2.
long double ld = 3.1415926;
int a{ld}, b = {ld};
列表初始化时,如果初始值存在丢失信息风险,编译器会报错。
long double ld = 3.1415926;
int a{ld}, b = ld;
这种不会报错,但是丢失了信息
3.
int &refVal = ival; refVal通过引用指向ival
int &refVal2; 错误,引用必须初始化
4.
int i = 42;
int *p;
int *&r = p; //r是对指针p的引用
r = &i; //对r赋值,就是对p赋值
*r = 0; //对r进行解引用,也就是对p指向的对象--> i进行操作
5.
const仅在本文件内有效
double dval = 3.14;
const int &ri = dval;
在执行时,编译器通过const int temp =dval;先产生一个临时的整型常量,
const int &ri = temp; //使ri绑定临时量,是非法的
6.
double dval = 3.14;
const double *cptr = &dval; //可以,但是不能通过cptr改变dval的值,dval的值可以用别的方式改变
7.
int i = 42;
int *const p = &i; //p是一个常量指针,将一直指向i ,可以通过*p修改i的值
const double pi = 3.14;
const double *const pip = π //pip是一个指向常量对象的指针常量
8.
顶层const表示指针本身是一个常量
底层const表示指针所指的对象是一个常量
底层const进行copy时,必须具有相同的底层const资格,一般非常量可以转换为常量,反之不行。
9.
constexpr int buff = 1024; //常量表达式
10
alias
typedef doubel wages; //wages是double的同义词
typedef wages base, *p; //base是double的同义词,p是double*的同义词
11.
常量指针
int * const p;
指向常量的指针
int const *p;
using SI = Sales_item;
12.
decltype返回表达式结果对应的类型
int i = 42, *p = &i, &r = i;
decltype(r + 0) b; //decltpye(r)是一个引用类型,想去看r所指向的类型,就可以通过(r + 0),(r + 0)是一个int类型的
decltype(*p) c; //*p是一个解引用,decltype将得到一个引用类型,因此要初始化。相当于int &c;
decltype((i)) d; //双层括号时,是一个引用
int a = 3, b = 4;
decltype(a = b) d = a; //赋值也会产生引用
13.
头文件保护
#ifndef SALES_DATA_H
#define SALES_DATA_H
#include <string>
****
#endif
习题
2.1 int, long, long long, short区别 float, double区别
int, long, short32位系统中都是4个字节32位,long long是8个字节
float单精度浮点数,至少6个有效数字,double双精度浮点数,至少10个有效数字。
2.27
(a)r必须是一个对象
(b)合法;p2是一个常量指针,一直指向i2,但是可以通过*p2去修改i2的值
(c)合法;这个比较有意思
const int &r = 42;可以编译过,
int &r = 42;不可以
引用在内部存放的是一个对象的地址,它是该对象的别名。对于不可寻址的值,如文字
常量,以及不同类型的对象,编译器为了实现引用,必须生成一个临时对象,引用实际上指
向该对象,但用户不能访问它。例如,当我们写:
double dval = 1024;
const int &ri = dval;
编译器将其转换成:
int temp = dval;
const int &ri = temp;
如果我们给ri 赋一个新值,则这样做不会改变dval,而是改变temp。对用户来说,就好
像修改动作没有生效(这对于用户来说,这并不总是好事情)
const 引用不会暴露这个问题,因为它们是只读的。不允许非const 引用指向需要临时对
象的对象或值,一般来说,这比“允许定义这样的引用,但实际上不会生效”的方案要好
得多。