c++ primer知识点-第2章 变量和基本类型

第2章 变量和基本类型

目录

2.1 基本内置类型

2.2 字面值常量

2.3 变量

2.4 const 限定符

2.5 引用

2.6 typedef 名字

2.7 枚举

2.8 类类型

2.9 编写自己的头文件

 

 

2.1 基本内置类型

  C++定义了一组表示整数、浮点数、单个字符和布尔值的算术类型,另外,还定义了一种称为void的特殊类型,void类型没有对应的值,仅用在有限的一些情况下,通常用作无返回值函数的返回类型。

C++算术类型

类型 含义 最小存储空间
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类型保证了足够的空间,能够存储机器基本字符集中任何字符对应的数值。因此,char类型通常是单个机器字节(byte)。wchar_t类型用于扩展字符集,比如汉语和日语,这些字符集中的一些字符不能用单个char表示。

  short、int和long类型都表示整型,存储空间的大小不同。一般,short类型为半个机器字长,int类型为一个机器字长,而long类型为一个或两个机器字长(在32位机器中int类型和long类型通常字长是相同的)。

  bool类型表示真值true和false,可以将算术类型的任何值赋给bool对象。0值算术类型代表false,任何非0的值都代表true。

1. 带符号和无符号类型

  整型int、short和long都默认为带符号型。要获得无符号型则必须指定该类型为unsigned。unsigned int类型可以简写为unsigned.

  char有三种不同的类型:普通char,unsigned char,signed char,但只有两种表示方式,可以使用unsigned char或signed char表示char类型。使用哪种char表示方式由编译器决定。

2. 整型值的表示

  定义一种类型使用8位表示,那么这种类型的unsigned型可以取值0到255。

3. 整型的赋值

  当我们试着把一个超出其取值范围的值赋给一个指定的对象时,结果会怎样?答案取决于这种类型是signed还是unsigned。对于unsigned类型来说,编译器会将该值对unsigned类型的可能取值数目求模,然后取得所得值,负数也一样。对于signed类型来说,由编译器决定。在实际操作中,大部分编译器会采用与unsigned类型相同的方式。

2.1.2 浮点型

  float单精度浮点值(32位);double双精度浮点值(64位);long double扩展精度浮点值(三个或四个字)。

  float型只能保证6位有效数字,double至少可以保证10位有效数字。

2.2 字面值常量

  值不能修改;只有内置类型的字面值。

1.整型字面值规则

  支持三种进制:十进制、八进制(以0开头的字面值常量)、十六进制(以0x或0X开头的)。字面值整数常量的类型默认为int或long类型,其精度取决于字面值,通过增加后缀,能够强制将字面值整数常量转换为long,unsigned或unsigned long,通过在数值后面加L或l指定常量为long类型,可通过在数值后面加U或u定义unsigned类型。同时加L和U就能够得到unsigned long类型的字面值常量。

2. 浮点字面值规则

  使用科学计数法时,指数用E或者e表示。默认的浮点字面值常量为double类型。在数值的后面加上F或f表示单精度。同样加上L或者l表示扩展精度(再次提醒,不提倡使用小写字母l)。

3. 布尔字面值和字符字面值

  单词true和false是布尔型的字面值;可打印的字符型字面值通常用一对单引号来定义:

4. 非打印字符的转义序列

  不可打印字符和特殊字符都用转义字符书写。转义字符都以反斜线符号开始:

5. 字符串字面值

  字符串字面值常量用双引号括起来的零个或者多个字符表示。不可打印字符表示成相应的转义字符。C++中所有的字符串字面值都由编译器自动在末尾添加一个空字符。存在宽字符串字面值,在字符串字面值前面加“L”,以一个宽空字符结束。

6. 字符串字面值的连接

  两个相邻的仅由空格、制表符或换行分开的字符串字面值(或宽字符串字面值)可连接成一个新字符串字面值。如果连接字符串字面值和宽字符串字面值结果是未定义的。

7. 多行字面值

  在一行的末尾加一反斜线符号可将此行和下一行当作同一行处理。反斜线符号必需是该行的尾字符——不允许有注释或空格符。同样,后继行行首的任何空格和制表符都是字符串字面值的一部分。正因如此,长字符串字面值的后继行才不会有正常的缩进。

2.3 变量

2.3.1  什么是变量

  变量提供了程序可以操作的有名字的存储区。C++中的每一个变量都有特定的类型,该类型决定了变量的内存大小和布局、能够存储于该内存中的值的取值范围以及可应用在该变量上的操作集。

  左值:左值可以出现在赋值语句的左边或右边;右值:右值只能出现在赋值的右边,不能出现在赋值语句的左边。

2.3.2  变量名

  变量名,即变量的标识符(identifier),可以由字母、数字和下划线组成。变量名必须以字母或下划线开头,并且区分大小写字母。

1. C++关键字

  关键字不能用作程序的标识符,标识符不能包含两个连续的下划线,也不能以下划线开头后面紧跟一个大写字母。有些标识符——在函数外定义的标识符——不能以下划线开头。

2. 变量命名习惯

  变量名一般用小写字母;标识符应使用能帮助记忆的名字;包含多个词的标识符书写为在每个词之间添加一个下划线,或者每个内嵌的词的第一个字母都大写。

2.3.3  定义对象

  每个定义都是以类型说明符(type specifier)开始,后面紧跟着以逗号分开的含有一个或多个标识符的列表。分号结束定义。

1. 初始化

  变量定义指定了变量的类型和标识符,也可以为对象提供初始值。C++支持两种初始化变量的形式:拷贝初始化和直接初始化拷贝初始化语法用等号(=),直接初始化是把初始化式放在括号中。

2. 使用多个初始化式

  对内置类型来说,拷贝初始化和直接初始化几乎没有差别。对类类型的对象来说,有些初始化仅能用直接初始化完成。

3. 初始化多个变量

  可以用同一个定义中前面已定义变量的值初始化后面的变量。已初始化变量和未初始化变量可以定义在同一个定义中定义。

2.3.4  变量初始化规则

1. 内置类型变量的初始化

  内置类型变量是否自动初始化取决于变量定义的位置。在函数体外定义的变量都初始化成0,在函数体里定义的内置类型变量不进行自动初始化。

2. 类类型变量的初始化

  类通过定义一个或多个构造函数来控制类对象的初始化,如果定义某个类的变量时没有提供初始化式,这个类也可以定义初始化时的操作。它是通过定义一个特殊的构造函数即默认构造函数来实现的。

2.3.5  声明和定义

  变量的定义为变量分配存储空间,还可以为变量指定初始值。在一个程序中,变量有且仅有一个定义。声明用于向程序表明变量的类型和名字。定义也是声明:当定义变量时我们声明它的类型和名字。可以通过使用extern关键字声明变量名而不定义它。不定义变量的声明包括对象名、对象类型和对象类型前的关键字extern,extern声明不是定义,也不分配存储空间。程序中变量可以声明多次,但只能定义一次。如果声明有初始化式,那么它可被当作是定义,即使声明标记为extern,只有当extern声明位于函数外部时,才可以含有初始化式。

2.3.6 名字的作用域

  定义在全局作用域中的名字可以在局部作用域中使用,定义在全局作用域中的名字和定义在函数的局部作用域中的名字可以在语句作用域中使用,等等。名字还可以在内部作用域中重新定义。

2.3.7  在变量使用处定义变量

  通常把一个对象定义在它首次使用的地方是一个很好的办法。

1. 定义const对象

  因为常量在定义后就不能被修改,所以定义时必须初始化。

2. const对象默认为文件的局部变量

  把一个非const变量定义在一个文件,假设已经做了合适的声明,就可在另外的文件中使用这个变量:

  除非特别说明,在全局作用域声明的const变量是定义该对象的文件的局部变量。此变量只存在于那个文件,不能被其他文件访问。通过指定const变量为extern,就可以在整个程序中访问const对象:

2.5 引用

  引用主要用作函数的形式参数。

1. 引用是别名

  因为引用只是它绑定的对象的另一名字,作用在引用上的所有操作事实上都是作用在该引用绑定的对象上。

2. 定义多个引用

3. const引用

  const引用是指向const对象的引用,将普通的引用绑定到const对象是不合法的。非const引用只能绑定到与该引用同类型的对象,const引用则可以绑定到不同但相关的类型的对象或绑定到右值。

2.6 typedef名字

  typedef让我们可以定义类型的同义词,typedef名字可以用作类型标识符。typedef通常被用于以下三种目的:

为了隐藏特定类型的实现,强调使用类型的目的。

简化复杂的类型定义,使其更易理解。

允许一种类型用于多个目的,同时使得每次使用该类型的目的明确。

2.7 枚举

1. 定义和初始化枚举

  默认地,第一个枚举成员赋值为0,后面的每个枚举成员赋的值比前面的大1。

2. 枚举成员是常量

  用来初始化枚举成员的值必须是一个常量表达式,枚举成员值可以是不唯一的,不能改变枚举成员的值。

3. 每个enum都定义一种唯一的类型

  枚举类型的对象的初始化或赋值,只能通过其枚举成员或同一枚举类型的其他对象来进行。

2.8 类类型

1. 设计类从其操作开始

  每个类都定义了一个接口(interface)和一个实现(implementation)。接口包括我们期望使用该类的代码执行的操作。实现一般包括该类所需要的数据。实现还包括用来定义该类但又不作一般性使用的函数。

2. 定义Sales_item类

  类定义以关键字class开始,其后是该类的名字标识符。类体位于花括号里面。花括号后面必须要跟一个分号。

编程新手经常会忘记类定义后面的分号,这是个很普遍的错误!

  类也可以包含0个到多个private或public访问标签(access label)。访问标签控制类的成员在类外部是否可访问。使用该类的代码可能只能访问public成员。

  每一个类都定义了它自己的作用域。也就是说,数据和操作的名字在类的内部必须唯一,但可以重用定义在类外的名字。

3. 类的数据成员

  一般不能把类成员的初始化作为其定义的一部分,而是通过称为构造函数的特殊成员函数控制初始化。

4. 访问标号

5. 使用struct关键字

  如果使用class关键字来定义类,那么定义在第一个访问标签前的任何成员都隐式指定为private;如果使用struct关键字,那么这些成员都是public。

2.9 编写自己的头文件

2.9.1  设计自己的头文件

1. 头文件用于声明而不是用于定义

  对于头文件不应该含有定义这一规则,有三个例外。头文件可以定义类、值在编译时就已知道的const对象和inline函数。

2. 一些const对象定义在头文件中

  如果const变量不是用常量表达式初始化,那么它就不应该在头文件中定义。

2.9.2  预处理器的简单介绍

1. 头文件经常需要其他头文件

2. 避免多重包含

  为了避免名字冲突,预处理器变量经常用全大写字母表示。

  预处理器变量的名字必须在程序中唯一。任何与预处理器变量相匹配的名字的使用都关联到该预处理器变量。

3. 使用自定义的头文件

  如果头文件名括在尖括号(< >)里,那么认为该头文件是标准头文件。编译器将会在预定义的位置集查找该头文件,这些预定义的位置可以通过设置查找路径环境变量或者通过命令行选项来修改。如果头文件名括在一对引号里,那么认为它是非系统头文件,非系统头文件的查找通常开始于源文件所在的路径。

 

作者: 勿慢牛

安全方向,化學/化工專業,主要關注學佛、計算化學、C++、Python、計算機、古文化、哲學、思維方向,渴求與有共同興趣的朋友交流,詳情請查看“關于”頁面。

发表评论

电子邮件地址不会被公开。 必填项已用*标注