C++ Primer
第二章 变量和基本类型
2.1基本内置类型
有算数类型和void类型;算数类型储存空间大小依及其而定。
算数类型表:
类型 |
含义 |
最小储存空间 |
---|---|---|
bool |
布尔型 |
- |
char |
字符型 |
8 |
wchar_t |
宽字符型 |
16 |
short |
短整型 |
16 |
int |
整型 |
16 |
long |
长整型 |
32 |
float |
单精度浮点型 |
6位有效数字 |
double |
双精度浮点型 |
10位有效数字 |
long double |
扩展精度浮点型 |
10位有效数字 |
2.1.1整型
包括整数字符和布尔型。
字符型:char和wchar_t,后者用于扩展字符集。
char有些实现中当做signed类型,而有些则被当做unsigned类型
内置类型的机器级表示:
让储存具有结构的基本方法是用块来处理储存;通常8位作为一个字节(1b=8B),32位或4个字节作为一个“字”。
可以将算数类型的任何值赋值给bool对象;0值算数类型代表false,非0代表true。
把一个超出其取值范围的值赋给一个特定类型时:
对于unsigned类型来说,编译器会对该值求模然后取所得值;对于signed类型,由不同编译器决定实际赋的值;
c++中,把负值赋值给unsigned对象是完全合法的,其结果是对该负数该类型的取值个数求模后的值。
在大多数机器中用long类型进行计算所付出的运行时代价远远高于int类型;而双精度计算代价相对于单精度可以忽略。
2.2字面值常量
只有内置类型存在字面值。
整形字面值规则0
20 //decimal
024 //octal 0(zero)24
0x24 //hexadecimal (or 0X24)
可以通过增加后缀,强制更改字面值常量类型。
浮点数字面值规则:
默认为double类型;加后缀F或f表示单精度;使用科学计数法时,指数用E或e表示。
用false or true表示布尔值
用将字符放在单引号内表示字符常量;前面加前缀L表示wchar_t类型。
可以将任何字符表示为以下形式通用转义字符:
ooo
这里ooo表示三个八进制数字。也可用十六进制转义字符定义字符:xddd
字符串字面值:双引号括起来的零个或多个字符。
为了兼容c,字符串字面值都由编译器在末尾添加一个空字符。
宽字符字面值,只需在前面添加前缀L。
两个相邻的仅由空格、制表符、换行符分开的同为字符串字面值或同为宽字符字面值,可连接成一个新字符串字面值或宽字符串字面值。字符串字面值和宽字符串字面值连接是未定义的。
2.3
c++是一门静态类型语言,在编译时会作类型检查。
2.3.2变量名
可以由字母数字先换线组成。变量名必须以字母或下划线开头,并且区分大小写。
2.3.4变量初始化规则
在函数体外定义的变量都初始化成0,在函数体里定义的内置类型变量不进行自动初始化。
2.3.5声明和定义
为了让多个文件访问相同的变量,c++区分了声明和定义。
使用关键字 extern 对变量进行声明。
一个变量可以被声明多次,但只能被定义一次。
如果声明由初始化式,那么它可被当做定义,如 extern int a = 10;
任何多个文件中使用的变量都需要有与定义分离的声明。在这种情况下,一个文件含有变量的定义,使用该变量的其他文件则包含该变量的声明。
2.3.6名字的作用域
作用域:用来区分名字的不同意义的上下文称为作用域。作用域是程序的一段区域。
2.4 const限定符
使用const把一个对象转换成常量,可以提高程序的可读性和可维护性。
因为常量在定义后就不能被修改,所以定义时必须初始化。
const对象默认为文件的局部变量,通过指定const变量为extern,就可以在整个程序中访问const对象。
非const变量默认为extern,要使变量能够在其他的文件中访问,必须显式地指定它为extern(P50)
2.5引用
引用是一种复合类型(用其他类型定义的类型)。
每一种引用都关联到某一其他类型,不可以定义引用的应用,但可以定义任何其他类型的引用。
初始化是指明引用指向哪个对象的唯一方法。
定义引用,如:int &r = i;
将普通的应用绑定到const对象是不合法的。
2.6 typedef
typedef用来定义类型的同义词。
使用typedef的目的:
隐藏特定类型的实现,强调使用类型的目的;
简化复杂的类型定义
允许一种类型用于多个目的,同时使得每次使用该类型的目的明确。
2.7枚举
定义和初始化
enum open_modes {input, output, append};
默认地,第一个枚举成员赋值为0,后面成员依次增1。
枚举成员是常量,用来初始化枚举成员的必须是常量表达式。
枚举成员的值可以重复。
每个enum都定义一种唯一的类型,枚举类型对象的初始化或赋值只能通过其枚举成员或者同一枚举类型的其他对象进行。
2.8类类型
定义类类型的最后必须有一个分号。
定义了类也就定义了一种新的类型, 类名就是该类型的名字。
定义变量和定义数据成员不是一个概念,由非常重要的区别。定义类的时候定义数据成员, 用定义完成的类类型定义对象的时候会根据相应的数据成员定义相应的变量。一般不能把类成员的初始化作为其定义的一部分。当定义数据成员时,只能指定该数据成员的名字和类型,类不是在类定义里定义数据成员时初始化数据成员,而是通过称为构造函数的特殊成员函数控制初始化。
类成员函数可以使用类的任何成员。
用class和struct定义类的唯一区别在于默认访问级别:class成员默认为private,struct默认为public。
2.9头文件
头文件一般包含类的定义,extern变量的声明和函数的声明。
编译和链接多个源文件(P58)。
头文件用于声明而不是用于定义。因为头文件包含在多个源文件中,所以不应该含有变量或函数的定义。例外:头文件可以定义类、值在编译时就已经知道的const对象(并非所有)和inline函数。这些实体可以在多个源文件中定义,只要每个源文件定义是相同的。
实践中不会有任何储存空间用于储存用常量表达式初始化的const变量。
如果const常量不是用常量表达式初始化,那么它就不应该在同文件中定义,相反,和其他变量一样,在一个源文件中定义并初始化,在同文件中添加它的extern。
预处理器用指定的头文件内容替代每个#include,因此设计头文件时,应使可以多次包含在同一源文件中。
预处理器变量的名字在程序中必须是唯一的。任何与预处理器变量相匹配的名字的使用都关联到该预处理器变量。
头文件保护符可以避免头文件的多重包含。