基本上所有语言都要提供以下特征:内置数据类型;表达式和语句;变量;控制结构;函数
大都采用:允许自定义数据类型和库来扩展:标准库正是利用这些机制定义了许多更复杂的类型,比如可变长字符串 string 、vector 等
c++是静态语言,变量和函数在使用前必须先声明,在编译的时候进行类型检查,相对应比如Python是在运行时进行类型检查
第一步:基本知识和标准库(第一部分内容)
chapter2:内置类型和介绍类型如何扩展
C++ 定义了一组表示整数、浮点数、单个字符和布尔值的算术类型 ,另外还定义了一种称为void 的特殊类型
1.整数,字符和布尔值统称为整型。int为32位,一个机器字长;short为半个机器字长;long为一个或两个机器字
2.整型可以由二进制精确表示,所以不存在精度问题,只存在越界问题。当越界赋值时,不会报错,只会警告,并使用该类型的取值个数进行求模取值。实质上是截取低取值位数(对超过8为的值付给char,只不过是截取低八位进行赋值,即进行取模运算)
3。最高位是1时为负
4.浮点数,float是32位的,double是64位的。一般采用double,因为其计算代价与float的精度代价相比是可以忽略的。
float只能保证6位有效数字(float只用23位来存储尾数),而double至少可以保证10位。
float取值范围是-3.4E38~3.4E38 double取之范围:-1.7E308~1.7E308
5.cout.setf(ios::fixed)进行追加标示位。fixed表示定点形式输出,scientific以科学表示法输出。应为有限n位二进制无法精确表示许多小数,所以就有了精确度问题,我们只能利用更大的n值来更精确的表示这个数。以fixed形式可以看到精度误差。(52.5+11.7不是精确等于64.2)。
关于float的精确度请看我转载的文章
6.字符串最后以空字符结尾
7. L'' ;L""为宽字符
变量提供了程序可以操作的有名字的存储区
8. 同一定义语句中不同变量的初始化应分别进行 int a=b=10;是错误的,会认为b未声明
9.变量初始化:直接初始化和复制初始化。复制初始化语法用等号(=),直接初始化则是把初始化式放在括号中。这里要理解复制初始化与赋值之间的区别
10.内置类型,作为全局变量时自动初始化为0;局部变量时不会自动初始化。
11.类类型,一般会有默认构造函数,所以可以不显示初始化
12.为初始化化变量会引起运行时错误。所以要特别注意,尤其是在程序结构比较乱的时候
13.Declarations and Definitions
定义只出现一次,而声明可以多次!
14.extern 声明不是定义,也不分配存储空间。事实上,它只是说明变量定义在程序的其他地方,(可以在别的文件中,不仅仅是头文件。确实extern会在别的文件中查找,但是声明其他文件中定义的变量要注意作用域,应该是全局变量,因为局部变量在编译时没错,但是运行时在链接的阶段局部变量销毁,就会出现运行时找不到该变量的定义!!!(其实关键不是全局不全局,主要是在声明使用该变量时,是在该变量的作用域中)),由编译器寻找(所以在同一个文件中如果该文件很大,extern可以帮助理解程序);
15.只有当 extern 声明位于函数外部时,才可以含有初始化式。
16.注意include头文件是引进声明,而非定义;头文件一般包含类的定义、extern 变量的声明和函数的声明
,因为头文件可能被多个源文件引入,但是变量定义只可以出现一次!!!声明可以出现多次。
17.局部变量可以与全局变量重名,并屏蔽全局变量,但是最好不要重名。
18.const常量不能修改,所以定义时必须初始化
19.const 对象默认为文件的局部变量,其作用域为定义它的文件,所以对声明方式而非include方式来在不同文件使用它时,必须extern const 来定义const常量;非 const 变量默认为 extern。
为何 const 对象局部于文件创建?
因为我们经常在头文件中定义const常量(使用常量表达式初始化),而头文件应该是引入声明而非定义,所以使const 对象局部于文件创建,每个包含该头文件的源文件就都有了自己的const常量,其名称和值一样!!!
20.引用:必须初始化,而且初始化后就绑定到一个对象,这种绑定是不会改变的,初始化是指明引用指向哪个对象的唯一方法。引用时绑定对象的别名,而且非const的应用必须用与该引用同类型的对象初始化。而const引用(只能读取不能修改)可以绑定不同但是相关类型的对象或者绑定到右值(字面值常量;表达式等)。
21.const引用是指向const对象的引用;
22.复制初始化要与赋值区分开!: :
(a) 中的定义和 (b) 中的赋值存在哪些不同?哪些是非法的?
(a) int ival = 0; (b) ival = ri;//ok
const int &ri = 0; ri = ival;//非法
const int test=0;
int &rt=test;//error
总结:只要是非const的变量或者引用,均可以使用任何值来赋值修改。当变量作为右值时其本质上就是一个值。
23.typedef定义类型的同义词,是编译过程的一部分,而define是原地展开,在预编译阶段完成
24.enum的成员是常量,不能改变其成员的值。注意枚举成员的值可以不唯一。枚举定义了一个新的类型。枚举类型对象的初始化和赋值,只能通过其枚举成员或同一枚举类型的其他对象来进行。
// point2d is 2, point2w is 3, point3d is 3, point3w is 4
enum Points { point2d = 2, point2w,
point3d = 3, point3w };
Points pt3d = point3d; // ok: point3d is a Points enumerator
Points pt2w = 3; // error
pt2w = polygon; // error: polygon is not a Points enumerator
pt2w = pt3d; // ok: both are objects of Points enum type
25.类类型:
定义变量和定义数据成员存在非常重要的区别:一般不能把类成员的初始化作为其定义的一部分。当定义数据成员时,只能指定该数据成员的名字和类型。类不是在类定义里定义数据成员时初始化数据成员,而是通过构造函数来初始化数据成员。
用 class 和 struct 关键字定义类的唯一差别在于默认访问级别:默认情况下,struct 的成员为 public,而 class 的成员为 private。
编译头文件是消耗时间的,使用预编译(预处理器)头文件来减少时间
26.对于头文件不应该含有定义这一规则,有三个例外。头文件可以定义类、值在编译时就已知道的 const 对象和 inline 函数。这些实体可在多个源文件中定义,只要每个源文件中的定义是相同的。