变量和基本类型
文章目录
C++ 算术类型
类型 | 含义 | 最小尺寸 |
---|---|---|
bool | 布尔类型 | 未定义 |
char | 字符 | 8位 |
wchar_t | 宽字符 | 16位 |
char16_t | Unicode字符 | 16位 |
char32_t | Unicode字符 | 32位 |
short | 短整型 | 16位 |
int | 整型 | 16位 |
long | 长整型 | 32位 |
long long | 长长整型 | 64位 |
float | 单精度浮点数 | 6位有效数字 |
double | 双精度浮点数 | 10位有效数字 |
long double | 扩展精度浮点数 | 10位有效数字 |
w_chart类型用于确保可以存放机器最大扩展字符集中的任意一个字符。
类型char16_t和char32_T为Unicode字符集服务。
内置类型的机器实现
可寻址的最小内存块被称为“字节(byte)”,存储的基本单元被称为“字(word)”
把负数转换成无符号数类似于直接给无符号数赋一个负值,结果等于这个负数加上无符号数的模。
切勿混用带符号类型和无符号类型
如果表达式里既有带符号类型又有无符号类型,当带符号类型取值为负时会出现异常结果,这是因为带符号数会自动地转换成无符号数。
指定字面值的类型
字符和字符串字面量
前缀 | 含义 | 类型 |
---|---|---|
u | Unicode16字符 | char16_t |
U | Unicode32字符 | char32_t |
L | 宽字符 | wchar_t |
u8 | UTF-8(仅用于字符串字面常量) | char |
整型字面值
后缀 | 最小匹配类型 |
---|---|
u or U | unsigned |
l or L | long |
ll or LL | long long |
浮点型字面值
后缀 | 类型 |
---|---|
f或F | float |
l或L | long double |
变量
对象是指一块能存储数据并具有某种类型的内存空间。
初始化与赋值
初始化:创建变量时赋予其一个初始值。
赋值:把对象的当前值擦除,而以一个新值来替代。
列表初始化
int units_sold{0};
C++11中当用于内置类型的变量时,如果我们使用列表初始化且初始值存在丢失信息的风险,则编译器报错。
声明与定义
声明使得名字为程序所知,一个文件如果想使用别处定义的名字则必须包含对那个名字的声明。
定义负责创建与名字关联的实体。定义还申请存储空间。
如果想声明一个变量而非定义它,就在变量名前添加关键字extern,而且不要显式地初始化变量。
extern int i; //声明i而非定义i
int j; //声明并定义j
如果extern语句包含初始值就不再是声明,而变成定义了。
extern int i = 345; //定义
在函数的内部无法初始化一个有extern关键字标记的变量。
::a 向全局作用域发出请求获取作用域操作符右侧名字对应的变量。
引用
引用(reference)为对象起了一个另外一个名字,引用类型引用(refers to)另外一种类型。通过将声明符写成&d的形式来定义引用类型。
int ival = 1024;
int &refVal = ival; //refVal指向ival
int &refVal2; //报错
引用必须要初始化!!!!!且无法令引用重新绑定到另外一个对象!!!!!!
引用即别名
引用并非对象,它只是为一个已经存在的对象所起的另外一个名字。
引用只能绑定在对象上,而不能与字面值或某个表达式的计算结果绑定在一起。
指针
引用不是对象,所有没有实际地址,不能定义指向引用的指针!!!!!
空指针
得到空指针的最直接的办法是用字面值nullptr来初始化指针(C++11标准)。nullptr是一种特殊类型的字面值,它可以被转换成任意其他的指针类型。
新标准下C++最好使用nullptr,避免使用NULL。
建议:初始化所有指针
void*
void*指针是一个特殊的指针类型,可用于存放任意对象的地址。
void*的限制:
不能直接操作void*指针所指的对象。
指向指针的引用
int *p;
int *&r = p; //r是一个对指针p的引用
当遇到一个比较复杂的指针或引用的声明语句时,从右向左阅读有助于弄清楚它的真实含义。
const限定符
默认情况下,const对象被设定为仅在文件内有效。当多个文件中出现了同名的const变量时,其实等同于在不同文件中分别定义了独立的变量。
在不同文件中共享同一const变量
对于const变量不管是声明还是定义都添加extern关键字。
// file_1.cpp文件
extern const int bufSize = fcn(); //定义并初始化了一个常量,该常量能被其他文件访问。
// file_1.h 文件
extern const int bufSize; //与file_1.cpp中定义的bufSize是同一个。
如果想在多个文件中共享const对象,必须在变量的定义之前添加extern关键字。
引用的类型必须与其所引用对象的类型一致,但是有两个例外:
在初始化常量引用时,允许用任意表达式作为初始值,只要该表达式的结果能转换成引用的类型即可。
常量引用仅对引用可参与的操作做出了限定,对于引用的对象本身是不是一个常量未作限定。
所谓指向常量的指针或引用,不过是指针或引用“自以为是”,它们觉得自己指向了常量,所以自觉地不去改变所指对象的值。
顶层const
顶层const可以表示任意的对象是常量,底层const则与指针和引用等复合类型的基本类型部分有关。
int i = 0;
int *const p1 = &i; //顶层const
const int ci = 42; //顶层const
const int *p2 = &ci; //底层const
const int *const p3 = p2; //底层const 顶层const
const int &r = ci; //底层const
当执行对象的拷贝操作时,顶层const不受什么影响。
底层const的影响不能忽视,当执行对象的拷贝操作时,拷入和拷出的对象必须具有相同的底层const资格,或者两个对象的数据类型必须能够转换。一般来说非常量可以转换为常量,但常量不能转换为非常量。
constexpr 和常量表达式
常量表达式是指不会改变并且在编译过程就能得到计算结果的表达式。字面值属于常量表达式,用常量表达式初始化的const对象也是常量表达式。
一个对象(或表达式)是不是常量表达式由它的数据类型和初始值共同决定。
constexpr 变量
C++11新标准规定,允许将变量声明为constexpr类型以便由编译器来验证变量的值是否是一个常量表达式。声明为constexpr的变量一定是一个常量,而且必须用常量表达式初始化。
constexpr int mf = 20;
constexpr int limit = mf + 1;
普通函数无法作为constexpr变量的初始值。新标准允许定义一种constexpr函数,可以用constexpr函数去初始化constexpr变量。
一个constexpr指针的初始值必须是nullptr或者0,或者是存储于某个固定地址的对象。
类型别名
- typedef
typedef double wages; //wages是double的同义词
typedef wages base, *p; //base是double的同义词, p是double* 的同义词。
- 别名声明:
using SI = Sales_item; // SI是Sales_item的同义词。
auto类型说明符
C++11新标准引入auto类型说明符,用它就能让编译器替我们去分析表达式所属的类型。auto让编译器通过初始值来推算变量的类型,auto定义的变量必须有初始值。
- 编译器以引用对象类型作为auto的类型
int i = 0, &r = i;
auto a = i; //a 是一个整数
- 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是一个指向整数常量的指针
- 如果希望推断出的auto类型是一个顶层const,需要明确指出:
const auto f = ci; // ci的推演类型是int, 但f是cosnt int 类型。
- 将引用的类型预设为auto:
auto &g = ci; //g是一个整型常量的引用,绑定到ci
auto &h = 42; //错误,不能为非常量引用绑定字面值
const auto &j = 42; //正确
设置一个类型为auto的引用时,初始值中的顶层常量属性仍然保留。
decltype类型指示符
C++11引入了新的类型说明符decltype,它的作用是选择并返回操作数的数据类型。编译器分析表达式并得到它的类型,却不实际计算表达式的值。
如果decltype使用的表达式是一个变量,则decltype返回该变量的类型(包含顶层const和引用在内).如果decltype使用的的表达式不是一个变量,则返回表达式结果所对应的类型。
如果表达式的内容是解引用操作,则decltype将得到引用类型!!!
!!!如果decltype的表达式是加上了括号的变量,结果将是引用。
!!!!decltype((variable))的结果永远是引用,而decltype(variable)结果只有当variable本身是一个引用时才是引用!!!!
自定义数据结构
C++11新标准规定,可以为数据成员提供一个类内初始值。创建对象时,类内初始值将用于初始化数据成员。没有初始值的成员将被默认初始化。