2.1 基本内置类型
概述
本小节介绍C++中的基本内置类型。基本内置类型是构成C++程序的基础,它们用于表示数据的不同形式,如整数、浮点数、字符等。理解和使用这些基本类型是编写C++程序的起点。
2.1.1 算术类型
C++的算术类型分为整型和浮点型。整型用于表示整数,浮点型用于表示带小数点的数值。
整型
整型包括各种不同的类型,以满足不同范围和精度的需求。
- 基本整型类型:
bool flag = true; // 布尔类型
char ch = 'a'; // 字符类型
signed char sch = -1; // 有符号字符类型
unsigned char uch = 255; // 无符号字符类型
short s = -32768; // 短整型
unsigned short us = 65535; // 无符号短整型
int i = -2147483648; // 整型
unsigned int ui = 4294967295;// 无符号整型
long l = -9223372036854775808L; // 长整型
unsigned long ul = 18446744073709551615UL; // 无符号长整型
long long ll = -9223372036854775807LL; // 长长整型
unsigned long long ull = 18446744073709551615ULL; // 无符号长长整型
浮点型
浮点型用于表示带小数点的数值,分为float
、double
和long double
三种类型,分别表示单精度、双精度和扩展精度浮点数。
- 基本浮点类型:
float f = 3.14f; // 单精度浮点型
double d = 3.14; // 双精度浮点型
long double ld = 3.14L; // 扩展精度浮点型
2.1.2 类型转换
类型转换用于在不同类型之间进行转换。C++支持隐式转换和显式转换。
隐式转换
隐式转换在需要时自动进行,不需要显式指定。
- 示例:
int i = 42;
double d = i; // int隐式转换为double
显式转换
显式转换需要使用强制转换运算符。
- C风格的显式转换:
double d = 3.14;
int i = (int)d; // double显式转换为int
- C++风格的显式转换:
double d = 3.14;
int i = static_cast<int>(d); // 使用static_cast进行显式转换
2.1.3 字面值常量
字面值常量是程序中直接使用的常量值,它们在程序运行时是固定不变的。字面值常量可以是整数、浮点数、字符、字符串等。理解字面值常量有助于编写更清晰、可读性更高的代码。
整数字面值
整数字面值表示整数,可以用不同的进制表示,如十进制、八进制和十六进制。
- 十进制:不带前缀的整数。
int dec = 42; // 十进制
- 八进制:以
0
开头的整数。
int oct = 052; // 八进制
- 十六进制:以
0x
或0X
开头的整数。
int hex = 0x2A; // 十六进制
浮点字面值
浮点字面值表示带小数点的数值,可以用科学计数法表示。默认情况下,浮点字面值是double
类型,可以通过后缀f
或F
指定为float
类型,通过后缀l
或L
指定为long double
类型。
- 普通表示:
double d = 3.14;
- 科学计数法表示:
double d2 = 3.14e2; // 3.14 × 10^2
- 指定类型:
float f = 3.14f; // float类型
long double ld = 3.14l; // long double类型
字符和字符串字面值
字符和字符串字面值用于表示字符和字符串。
- 字符字面值:用单引号括起来的单个字符。
char c = 'a';
char newline = '\n'; // 转义字符
- 字符串字面值:用双引号括起来的一串字符。
const char* str = "Hello, World!";
布尔字面值和指针字面值
C++中还包括布尔字面值和指针字面值。
- 布尔字面值:
true
和false
。
bool flag = true;
- 指针字面值:
nullptr
表示空指针。
int* p = nullptr;
重点与难点分析
重点:
- 基本数据类型:理解整型和浮点型的不同类型及其适用范围。
- 类型转换:掌握隐式转换和显式转换的用法,特别是C++风格的显式转换。
难点:
- 类型转换:初学者容易混淆隐式和显式转换的用法,需要通过练习掌握。
总结与提高
本节总结:
- 了解了C++中的基本内置类型,包括整型和浮点型。
- 学习了类型转换的概念和具体用法,包括隐式转换和显式转换。
提高建议:
- 多练习基本类型的使用:通过编写各种小程序,熟悉不同基本类型的定义和操作。
- 深入理解类型转换:特别是C++风格的显式转换,通过实际应用加深理解。
- 在算术运算中不要使用chat或者bool类型,因为chat有可能是signed chat,也可能是unsigned chat,具体由编译器来决定,而bool没有规定存储的大小。
- 执行浮点运算时选用double,这时因为float通常精度不够而且双精度浮点运算和单精度浮点运算的计算代价差不多,甚至在某些平台上可能双精度还更快。
2.2 变量
概述
本小节介绍C++中的变量,包括变量的定义、初始化、作用域和生命周期等。变量是程序中用于存储和操作数据的基本单元,理解变量的概念和使用方法是编写C++程序的基础。
2.2.1 变量定义
在C++中,变量的定义包括变量类型和变量名,可以在定义时进行初始化。
- 基本语法:
类型 变量名 = 初始值;
- 示例:
int i = 0; // 定义一个整型变量并初始化为0
double d = 3.14; // 定义一个双精度浮点型变量并初始化为3.14
变量初始化是为变量赋初值,可以在定义时进行。C++支持多种初始化方式,包括拷贝初始化、直接初始化和列表初始化。
拷贝初始化
拷贝初始化使用赋值运算符将初始值赋给变量。
- 语法:
int i = 0;
double d = 3.14;
直接初始化
直接初始化使用括号将初始值赋给变量。
- 语法:
int i(0);
double d(3.14);
列表初始化
列表初始化使用花括号将初始值赋给变量,C++11引入的这种方式可以防止窄化转换(narrowing conversion)。
- 语法:
int i{0};
double d{3.14};
2.2.2 变量声明和定义的关系
在C++中,声明和定义是两个不同的概念。理解变量的声明和定义之间的关系有助于编写更清晰和模块化的代码。
变量声明
变量声明告诉编译器变量的类型和名字,但不分配存储空间。声明通常出现在头文件中,以便在多个文件中共享变量。
- 示例:
extern int i; // 声明一个整型变量i
extern double pi; // 声明一个双精度浮点型变量pi
- 注意:
extern
关键字表示声明而非定义。声明告诉编译器变量已经定义在其他地方。
变量定义
变量定义不仅告诉编译器变量的类型和名字,还分配存储空间并可以初始化变量。定义通常出现在源文件中。
- 示例:
int i = 42; // 定义一个整型变量i并初始化为42
double pi = 3.14159; // 定义一个双精度浮点型变量pi并初始化为3.14159
声明和定义的区别
- 声明:
-
- 告诉编译器变量的存在及其类型。
- 不分配存储空间。
- 使用
extern
关键字。
- 定义:
-
- 告诉编译器变量的存在及其类型。
- 分配存储空间。
- 可以进行初始化。
- 示例:
// 声明
extern int x; // 告诉编译器变量x存在且类型为int
// 定义
int x = 10; // 告诉编译器变量x存在且类型为int,并分配存储空间和初始化
多文件程序中的声明和定义
在多文件程序中,变量的声明和定义通常在不同的文件中。通过声明和定义的分离,可以实现代码的模块化和重用。
- 头文件(declarations.h):
extern int global_variable; // 声明全局变量
- 源文件1(file1.cpp):
#include "declarations.h"
int global_variable = 100; // 定义全局变量
int main() {
// 使用global_variable
return 0;
}
- 源文件2(file2.cpp):
#include "declarations.h"
void some_function() {
// 使用global_variable
}
2.2.3 变量的作用域
变量的作用域是指变量在程序中可见并且可以被访问的区域。C++中的变量作用域分为全局作用域、局部作用域和块作用域。