第2章 变量和基本类型

2.1基本内置类型

基本内置类型包括,算术类型(arithmetic type)和空类型(void),当函数不返回任何值时,使用空类型作为返回类型。

2.11算术类型

算术类型分为两类:整形(包括布尔型)和浮点型

不同算术类型所占的内存空间不尽相同,在不同机器上也有一定差别,C++标准只规定了尺寸的最小值。

  • bool 布尔类型 最小尺寸未定义(常见为16位)
  • char 字符 最小尺寸8位
  • wchar_t 宽字符 最小尺寸16位
  • short 短整型 最小尺寸16位
  • int 整型 最小尺寸16位(但常见的为32位)(整数默认类型)
  • long 长整型 最小尺寸32位
  • long long 长整型 最小尺寸64位
  • float 单精度浮点数 6位有效数字
  • double 双精度浮点数 10位有效数字(浮点数默认类型)
  • long double 扩展精度浮点数 10位数字

以下是常见的算术类型字节数。

 

 

布尔类型只有两个取值,true(非0)和false(0),大多占一个字节

char16_t 在字符前声明u

char32_t 在字符前声明U 二者均为无符号类型,Unicode字符。

选择类型的经验准则:

  • 明知数值不可能为负时,选用无符号类型
  • 一般使用int执行整数运算,short经常范围不足,int范围不足时改用long 或者long long
  • 浮点数运算首选double,float常常会精度不足

2.1.2类型转换

 将对象从一种给定的类型转换(convert)为另一种相关的类型。

类型所能表示的值的范围决定了转换的过程:

  • 当我们把一个非布尔类型的算数值赋给布尔类型时,初始值为0则结果为false,初始值非0则结果为true
  • 当我们把一个布尔值赋给非布尔类型时,初始值为false则结果为0,初始值为true则结果为1
  • 当我们把一个浮点数赋给整数时,将会只保留整数部分,截断小数部分
  • 当我们把一个整数值赋给浮点数时,继承整数部分,小数部分记为0,如果整数所占的空间超过了浮点类型的精度范围,可能会产生精度损失。
  • 当我们赋给无符号类型一个超出它表示范围的值时,结果是初始值对无符号类型表示总数(最大值加一)取模后的余数。
  • 当我们赋给有符号类型一个超出它表示范围的值时,结果是未定义的。

1、非赋值运算的自动类型转换

转换核心原则:保证运算的精度不降低

  • 水平方向的转换:char、short转为int,unsigned short 转为unsigned,long转为unsigned long,float转为double,这样都不会损失精度
  • 竖直方向的转换:int转为unsigned,unsigned 转为 unsigned long,unsigned long转为double  竖直方向的转换包括有符号转为无符号,整型转为浮点型,可能存在精度丢失等问题,慎重进行。

2、赋值运算的类型转换

进行赋值运算时,将赋值号 右侧表达式的类型 自动转换成 左侧变量 的类型,右类型转左类型。

3、强制类型转换

建议:不要进行隐式的数据转换,可能产生不可知的问题。避免无法预知和依赖于实现环境的行为,写出可移指的程序。

 2.1.3 字面值常量

整型和浮点型字面值

整型字面值可以写成十进制、八进制、十六进制。0开头的表示八进制数,0x或0X(分别对应a~f大小写)开头的表示十六进制数。整型字面值一般默认为int

浮点型字面值表现为一个小数或以科学计数法表示的指数,指数部分用e或E表示。浮点型字面值一般默认为double,需要为float时,在后面加上f

字符和字符串字面值

单引号括起来的一个字符称为char型字面值,双引号括起来的零个或多个字符称为字符串型字面值。字符串字面值实际上是由常量字符构成的数组,每个字符串的末尾会添加一个空字符('\0'),所以字符串字面值的实际长度要比其内容多1.

当两个字符串字面值位置紧邻且仅由空格、缩进和换行符分隔,则它们实际上是一个整体。

转义序列

有两类字符无法直接使用,一类是不可打印字符,如退格或其他控制字符,因为它们没有可视的图符;另一类是在C++中有特殊含义的字符(单引号、双引号、问号、反斜杠)。

要表示这两类字符,都要用到转义序列(escape sequence),转义序列均以反斜线(\)开始。C++中的转义序列包括:

换行符 \n (new line) 横向制表符 \t (transverse)  纵向制表符\v(vertical)  退格符 \b(back)  报警(蜂鸣)符 \a   双引号\''  单引号\'  反斜线\\  问号\?  回车符\r  进纸符\f

泛化的转义序列可以用\后跟八进制数字 或者 \x后跟十六进制数字表示,一般默认数字对应的是ASCII字符。\后面最多只能跟3个八进制数字,\x后没有这个限制。通常与指定字面值类型结合使用。

指定字面值的类型

前缀用于修饰字符字面值

  • u    表示Unicode 16字符    类型为char16_t
  • U    表示Unicode 32字符    类型为char32_t
  • L    表示宽字符    类型为wchar_t
  • u8    表示UTF-8(仅用于字符串字面常量)   类型为char

后缀用于修饰数字字面值

整型字面值后缀:

  • u or U   表示unsigned
  • l or L    表示long
  • ll or LL    表示long long
  • u 和 l 、ll之间可以组合为ul、ull分别表示unsigned long 和 unsigned long long

浮点型字面值后缀:

  • f or F    表示float
  • l or L    表示long double

布尔字面值为true 和 false ,指针字面值为nullptr

2.2变量

变量是一个具名的、可供程序操作的存储空间。

2.2.1 变量定义

变量定义的基本形式是:类型说明符(type specifier),随后紧跟一个或多个变量名,变量名之间以逗号分隔,最后以分号结束。每个变量名的类型都由类型说明符指定,定义时还可以给一个或多个变量赋值。

初始化(initialized)

C++中的初始化和赋值是两个完全不同的操作,初始化是创建一个内存空间,该内存空间与某个变量绑定,然后往该内存空间写入初始值。赋值是把对象的当前值擦除,写入一个新的值。

 列表初始化

定义变量a等于0 可以用以下四种方法

  • int a = 0;
  • int a =  {0};
  • int a {0};
  • int a (0);

默认初始化

定义变量时如果没有指定初始值,则变量被默认初始化。此时变量被赋予了默认值,默认值由变量类型和定义变量的位置决定。

如果内置类型(算术类型)的变量未被初始化,变量定义在任何函数体之外时默认为0;定义在函数体内部时,变量将不被初始化,此时变量的值未被定义。对于string类型的变量,因为string类型本身接受无参数的初始化方式,所以不论定义在函数内还是函数外都被默认初始化为空串。

自定义类的变量的初始值由类自己决定,由类提供默认值或者显式初始化。

建议定义时就初始化每一个内置类型的变量。

2.2.2 变量声明和定义的关系

C++支持分离式编译,允许将程序分割为若干个文件,每个文件可被独立编译。例如std::cout和std::cin定义于标准库文件,我们却可以使用。

为了支持分离式编译,C++将声明(declaration)和定义(definition)区分开来。

  • 声明使得变量名为程序所知,规定了变量的类型和名字。一个文件如果想使用别处定义的名字则必须包含对那个名字的声明,例如声明#include <iostream>
  • 定义负责创建与名字关联的实体,也规定了变量的类型和名字,还申请了存储空间,也许会为变量赋初始值。

区分声明与定义:

  • 先看有没有显示初始化,有则是定义;
  • 再看有没有extern ,没有初始化且有extern 则为声明,否则为定义。
  • 例如extern int i; 为声明         int j; 为定义    extern int i = 0; 为定义(包含了初始化的声明算作定义,也叫声明并定义)

变量只能定义一次,不能重复定义,但可以被多次声明。所以变量的定义只能出现在一个文件中,多个文件均可以声明然后调用。

C++是一种静态类型语言(statically typed),在编译阶段检查类型是否合法(type checking)

2.2.3 标识符

C++标识符(identifier)

posted @ 2021-11-09 23:46  海萌萌萌萌萌萌  阅读(152)  评论(0编辑  收藏  举报