第二章 变量和基本类型学习笔记(第一遍阅读)
- C++语言提供了一套基础内置类型,分为非常量和常量;
- C++语言可以定义复合类型(指针、引用等);
- C++语言还允许用户自定义类型(类);
- C++库通过类提供了一套高级抽象类型(输入输出、String);
基本内置类型
算数类型(arithmetic type)和空类型(void)
算数类型:
bool
char % 8位
wchar_t % 宽字符 16位
char16_t % Unicode字符 16位
char32_t % Unicode字符 32位
short %16位
int %16位
long %32位
long long %64位
float
double
long double
整形
表示整数、字符和布尔值的算术类型。
bool型 false/true;字符型有两种,char和wchar_t,wchar_t用于扩展字符集。
除bool类型外,其他整形可以是有符号(signed)也可以是无符号(unsigned)。int、short、long默认是signed,除非指定为unsigned。
char有三种不同的类型:char、signed char、unsigned char。
当使用char时,由编译器决定使用哪种表示方式来表示a(signed char或unsigned char)。
浮点型
通常float(单精度)用一个字(32位)表示,double用两个字(64位)表示,long double用三个或四个字(96或128位)表示。类型的取值范围决定了浮点数的有效数字位数。
实际应用中类型选择建议:明确知晓数值不为负,选择无符号类型;使用int进行整数运算,超出范围用long long;执行浮点运算选用double。
变量
对C++程序员来说,变量和对象一般可以互换使用。
变量定义: 类型说明符+变量名
初始化:当对象在创建是获得了一个特定的值,这个对象被初始化,初始化不同于赋值。
声明和定义:
包含了显示初始化的声明即为定义。
extern int i;%声明i而不定义i
int i; %声明并定义i
extern int i=0; %定义
如果要在多个文件中使用同一个变量,就必须将声明和定义分离。变量的定义必须出现且只能出现在一个文件中,其他用到该变量的文件必须对其声明但不能重复定义。
复合类型
引用 “左值引用”
引用相当于为对象的别名,&d,d为声明得变量名。
引用必须初始化,当定义引用时,程序会把引用和变量的初始值绑定在一起。
引用本身不是一个对象,所以不能定义引用的引用。
指针
指针是指向另一种类型的复合类型。
指针本身是一个对象,允许复制和拷贝。
指针无须在定义时赋初值。
建议初始化所有指针,使用未经初始化的指针是引发运行时错误的一大原因。
指针定义和利用指针访问对象:
int ival=2;
int *p=&ival; % &取地址符
int *p=0; %*解引用符
cout<<ival;
空指针:
int *p1=NULL;
int *p2=nullptr;
int *p3=0;
void指针,一种特殊的指针,可以存放任意对象的地址。
指向指针的指针:
int ival=2;
int *p1=&ival;
int **p2=&p1;% **表示指向指针的指针
指向指针的引用:
int ival=2;
int *p;
int *&r=p; %r是一个对指针*p的引用
r=&ival;
*r=0; %解引用r 解引用*p,得到ival
const限定符
const限定符可以对变量的类型加以限定
const int bufSize=512;
const对象一旦创建后其值就不能再改变,所以const对象必须初始化。
默认状态下,const对象尽在文件内有效,如果想在多个文件内共享const对象,必须在变量的定义之前加extern关键字。
常量的引用,是对const的引用,不能用作修改它所绑定的对象。
const int c=1024;
const int &r=c;
r=42; %错误 r绑定的对象是const不能修改值
int &r1=c; %错误 r1不是const
对const的引用可能引用一个非const的对象
int i=2;
int &r1=i;
const &r2=i; %r2也可绑定对象i,但不允许通过r2修改i的值
r1=0;
r2=0; %错误
const指针,允许把指针本身定为常量,常量指针必须出初始化,而且一旦初始化后,指针值(地址值)就不允许改变。
int e=2;
int *const cur=&e; %cur一直指向e
const double p=3;
const double *p1=&p;%p1是一个指向常量对象的常量指针
p1=0; %错误
*cur=0;%正确 e=0
顶层const:指针本身是const
底层const:指针所指的对象是个const
常量表达式:是指值不会改变,在编译过程就能得到计算结果的表达式。将变量声明为constexpr类型可以由编译器验证变量的值是否是一个常量表达式。
在constexpr声明中如果定义了一个指针,限定符constexpr仅对指针有效,对其所指的对象无效。
const int *p=nullptr;%p是一个常量指针
constexpr int *q=nullptr; %q是一个指向常量的指针
处理类型
类型别名
类型别名与类型的名字等价,只要是类型的名字能出现的地方,就能使用类型别名。
两种方法可用于定义类型别名。
- 传统方法
typedef double wages;%wages 是 double的同义词
typedef wages base, *p;%base是double的同义词,p是double*的同义词
- 新标准 别名声明
using SI=sales_item
auto类型说明符
C++11新标准引入了auto类型说明符,用它就能让编译器替我们去分析表达是所属的类型。
auto item=val1+val2;
auto 一般会忽略掉顶层 const,同时底层 const 则会保留下来:
const int ci = i, &cr = ci;
auto b = ci; % b 是一个整数(ci 的顶层 const 特性被忽略掉了)
auto c = cr; %c 是一个整数
auto d = &i; % d 是一个整型指针
auto e = &ci;% e 是一个指向整数常量的指针(对常量对象取地址是一种底层 const )
如果希望推断出的 auto 类型是一个顶层 const,需要明确指出:
const auto f = ci; %ci 的推演类型是 int, f 是 const int
将引用的类型设为 auto,此时原来的初始化规则仍然适用:
auto &g = ci; // g 是一个整型常量引用,绑定到 ci
auto &h = 42; // 错误,不能为非常量引用绑定字面值
const auto &j = 42; // 正确,可以为常量引用绑定字面值
decltype类型指示符
decltype的作用是选择并返回操作数的数据类型,但并不实际计算表达式的值。
如果使用的表达式是一个变量,则 decltype 返回该变量的类型(包括顶层 const 和引用在内):
const int ci = 0, &cj = ci;
decltype(ci) x = 0; %x 的类型是 const int
decltype(cj) y = x; %y 的类型是 const int&,y 绑定到变量 x
decltype(cj) z; % 错误,z 是一个引用,必须初始化
decltype 的表达式如果是加上了括号的变量,结果将是引用。
decltype((i)) d; % 错误,d 是 int&,必须初始化
decltype(i) e; % 正确,e 是一个未初始化的 int
切记:decltype((variable))(双层括号)的结果永远是引用,而 decltype(variable)结果只有当 variable 本身就是一个引用时才是引用。