Chapter2(变量和基础类型)--C++Prime笔记

时间:2022-05-22 20:46:54
数据类型选择的准则:
①当明确知晓数值不可能为负时,选用无符号类型。
②使用int执行整数运算。在实际应用中,short常常显得太小而long一般和int有一样的尺寸。如果运算范围超过int的表示范围,则选用long long。
③在算术表达式中不要使用char或bool,只有在存放字符或布尔值时才使用它。因为类型char在一些机器上是有符号的,而在一些机器上又是无符号的,所以使用char进行算术运算特别容易出问题。如果真的需要使用一个不大的整数,那么明确指出它的类型是signed char还是 unsigned char。
④执行浮点数运算选用double,这是因为float的精度通常不够而双精度浮点数和单精度浮点数的计算代价相差无几。事实上,对于某些机器来说,双精度运算甚至比单精度运算还要快。long double提供的精度在一般情况下不用用到,况且它带来的运算时的消耗也不容忽视。

易错点:常量指针,常量都不可以赋给非常量指针,反之都可。(合法的话,你就可以通过这个指针去修改它了)


1.long long 类型是在C++11中新定义的。


2.字符类型的变量有三种,char,unsigned char,signed char.三种类型的对象在存储介质中的表现形式是一样的(都是一个占8bit的01串,只是解析的时候不同),而char的类型是根据编译器来决定的,VC编译器、x86上的GCC都把char定义为signed char,而arm-linux-gcc却把char定义为 unsigned char。

3.带符号数和无符号数进行运算的时候,带符号数会自动转换为无符号数。


4.如果两个字符串字面值位置紧邻且仅由空格,缩进,和换行符,则它们实际上使一个整体。

5.对象是指一块能存储数据并具有某种类型的内存空间。

6.当一次定义了两个或者多个变量时,对象的名字随着定义也就马上可以使用。因此在同一条定义语句中,可以先用定义的变量初始化后定义的变量。

7.初始化不是赋值,初始化的含义是创建变量时赋予其一个初始值,而赋值的含义是把对象的当前值擦出,而以一个新值来替代。

8.当我们使用列表初始化且初始化值存在丢失信息的风险,则编译器将报错。

9.内置类型的变量未被显式的初始化,它的值由定义的位置决定。定义于任何函数体之外的的变量被定义为0.定义在函数体内部的内置类型的变量将不被初始化。任何拷贝或者以其他形式访问此类值将引发错误。

10.每个类各自决定其初始化对象的方式。

11.任何包含了显式初始化的声明即成了定义。显式初始化与extern的作用抵消,是声明变成了定义。另外,在函数体内初始化一个由extern关键字标记的变量将引发错误。

12.定义标识符的规则:由于为标准库保留了一些名字。
用户自定义的标识符中不能连续出现两个下画线,也不能以下划线紧连着大写字母开头。此外,定义在函数体外的标识符不能以下画线开头。
变量名一般小写。
用户自己定义的类名一般以大写字母开头。

13.因为全局作用域并没有名字,所以当作用域操作符左侧为空的时,向全局作用域发出请求获取作用域操作符右侧名字对应的变量。

14.引用并非对象,没有实际地址,相反的,它只是为了一个已经存在的对象起的另一个别名。除个别例外,所有的引用的类型都要和与之绑定的对象向匹配(例外:初始化常量引用时允许用任意表达式作为初始值----这其中其实自动转换会生成临时量)。而且,引用只能绑定在对象上,而不能与字面值或某个表达式的计算结果绑定在一起。引用定义时就必须初始化。

15.解引用符:*

15.void *指针类型可以存放任意对象的地址,但是不能直接操作void *指针所指的对象。即以void *的视角来看内存空间也就仅仅是内存空间,没办法访问内存空间中所存的对象。

16.对于const关键字修饰的对象来说,具体实现过程其实是编译器在编译的过程中把用到该变量的地方都替换为对应的常量。
而默认情况下,const对象被设定为仅在文件内有效。当多个文件中出现了同名的const变量时,其实等同于在不同文件中分别定义了独立的变量。
如果想在多个文件*享const对象,必须在其定义声明之前都加入extern关键字。

17.使用const引用可以引用一个非const对象。

18.一般来说,指针的类型和其所指的对象的类型必须一致,但是特例就是允许一个常量指针指向一个非常量对象

19.常量表达式:指值不会改变并且在编译过程就能得到计算结果的表达式。

20.即使使用const关键字修饰了一个变量,但是这个变量还是不能确定是不是常量表达式
比如const int sz = get_size();这里的sz必须到具体运行的时候才能获取到。因此在C++11中加入了一个声明constexpr.由constexpr声明的变量一定是常量。

21:而一般只有引用,指针,算术类型才能用constecpr来修饰,而用其修饰也有严格的初值限制,constexpr指针必须为nullptr或者0或者存储与某个固定地址的对象。一般来说,定义在函数体外的全局变量的存储地址和用static定义的变量的存储地址是固定的,而函数体内定义的变量的存储地址不是固定的。
而需要注意的一点是,当用constexpr声明中定义了一个指针,咋限定符constexpr只对指针有效,与指针所指的对象无光。

22:如果某个类型别名指代的是复合类型或者常量,那么把它用到声明语句里会出大问题 C++Prime P61

23.decltype和auto的区别
①对引用变量的不同之处:auto将引用变量赋给变量后,变量的类型为引用变量所对应的变量的类型。而decltype则是为引用类型。例子如下:
int i = 0,&r = i;
//same
auto a = i;
decltype (i)b = i;
//different
auto c = r; c为int 类型
decltype (r)d = r;//d为int &类型
②处理底层const的方式不同
auto一般会忽略掉顶层的const,同时底层的const会被保留下来
例子:
const int ci = i,&cr = ci;
auto b = ci;整数
auto c = cr;整数
auto d = &i;整型指针
auto e = &ci;指向整数常量的指针
decltype 则会返回该变量的完整类型(包括顶层const和引用在内)
例子:
const int ci = 0,&cj = ci;
decltype (ci) x = 0;const int 型
decltype (cj) y = x;const int 型
decltype (cj) z ;错误,z是一个引用,引用必须初始化

另外decltype ((variable))  (注意是双层括号)的结果永远是引用,而decltype(variable)结果只有当variable本身是一个引用的时候才是一个引用。

24.类体内定义的名字必须唯一,但是可以与类外部定义的名字重复。

25.类体右侧的结束花括号后必须加一个;这是因为类体后可加变量名以示对该类型对象的定义。