基础算法 - 数据类型及标准库
一、常用数据类型
1. 无值类型 void
2. 小整数值类型 short
3. 整数值类型 int
4. 长整数值类型 long long
5. 无符号整数类型 unsigned short/unsigned int/unsigned long long
6. 符号值类型 char
7. 字符串值类型 string
8. 布尔类型 bool
9. 单精度浮点值类型 float
10. 双精度浮点值类型 double
11. 扩展双精度浮点值类型 long double
12. 常量值类型 const
1)无值类型
void 类型没有值,因此不可以用来声明一个变量,但可以用来声明函数,代表该函数没有返回值。
void xxx(int xxx,int yyy){ ...
... return; }
2)整数值类型
- 小整数值
short 类型声明的变量表示至少 16 位整数,其中首位为符号位,因此 short 类型声明的变量 x 必须满足 -215≤x<215。(-32768 ≤ x ≤ 32767)
unsigned short 类型则满足 0 ≤ x<216。(0 ≤ x ≤ 65535)
- 整数值
int 类型声明的变量表示至少 32 位整数,其中首位为符号位,因此 int 类型声明的变量 x 必须满足 -231≤ x<231。(-2,147,483,648 ≤ x ≤ 2,147,483,647)
unsigned int 类型则满足 0 ≤ x<232。(0 ≤ x ≤ 4,294,967,295)
- 大整数值
long long 类型声明的变量表示至少 64 位整数,其中首位为符号位,因此 long long 类型声明的变量 x 必须满足 -263≤ x<263。(-9,223,372,036,854,775,808 ≤ x ≤ 9,223,372,036,854,775,807)
unsigned long long 类型则满足 0 ≤ x<264。(0 ≤ x ≤ 18,446,744,073,709,551,616)
short x=32767; unsigned short x=65535; int x=2147483647; unsigned int x=4294967295; long long x=9223372036854775807; unsigned long long x=18446744073709551616;
3)字符值类型
- 符号值
char 类型声明的变量可以存储单个字符,位数为 8 位。所有字符均借助 ASCII 码于整数对应。
char 类型声明的变量 x 在 ASCII 码中对应的编号为 -128 ≤ x ≤127。
unsigned char 类型声明的变量 x 在 ASCII 码中对应的编号为 0 ≤ x ≤255。
char x='a';
// ASCII 码常用编号 48-57:'0'-'9' 65-90:'A'-'Z' 97-122:'a'-'z'
- 字符串值
string 类型声明的变量用于存储多个字符组成的字符串。
string 类型也可以用 char 类型数组代替。
使用 string 类型前,要引用 <csting> 或 <string.h> 头文件
#include<cstring> #include<string.h> string x="abcdefghijklmn";
4)布尔类型
bool 类型声明的变量只有两种取值 true(1) 或 false(0)
一个 bool 类型变量占 8 位空间。
bool x=true;
5)浮点值类型
- 单精度
float 类型声明的变量用于存储小数,最大值为 3.4×1038,精度在小数点后 6-9 位。
float 类型声明的变量占 32 位空间。
float x=0.0;
- 双精度
double 类型声明的变量用于存储小数,最大值为 1.8×10308,精度在小数点后 15-17 位。
double 类型声明的变量占 64 位空间。
double x=0.0;
- 扩展双精度
long double 类型声明的变量用于存储小数,最大值为 1.2×104032,精度在小数点后 33-36 位或 18-21 位(因电脑而异)。
double 类型声明的变量占 128 位(或 ≥80 位)空间。
long double x=0.0;
6)常量值类型
const 类型声明的变量一经声明不可改变。
const 无法决定变量的形式,因此应在 const 后面额外编写变量的类型。
const int x=1000;
7)类型转换
- 整转整
较小整数类型可直接转换为较大整数类型,较大整数类型转较小整数类型时保留靠右几位的值。
- 布转整
ture变1,false变0。
- 符转整
依照 ASCII 码进行转换。
- 浮转整
舍弃小数部分。
- 整转浮
小数部分为 0 。
- 符转浮
先转整,再转浮。
- 转布
0 则 false,非 0 则 true。
二、高级数据类型
1. 数组
2. 指针
3. 结构体
4. 联合体(23年新)
1)数组
数组有名字,数组内存储的变量没有名字,依靠地址访问。
数组内的变量的类型由数组类型决定。
数组的长度大小一经声明无法改变。这个长度必须是一个常量。
const int d=1000; int a[d];//一个大小为1000的数组 //int:数组类型 //a:数组名称 //d:数组大小
- 数组的访问
想要访问一个数组中的元素,只需要在数组名称后编写访问元素的下标即可,形如:a[i]。
当越界访问,即访问下标超过数组长度时,将会造成无法预料的后果,如段错误、RE、输出奇怪的数或编码、修改预期之外的数值等。
- 多维数组
多维数组的本质是”数组中的数组中的数组……“。声明多维数组时需要引用多个下标。二维数组如下:
int a[N][N]; int x=a[i][j];
2) 指针
程序中,每一个变量都有一个地址,即物理存储在内存中的位置。而指针类型变量存储的就是其他变量的地址。
- 指针的声明、赋值、引用
指针变量的类型为类型名后加上一个星号 *。
int* p;
我们可以通过取地址符 & 来获得一个变量的地址,并将这个地址赋给指针(这个变量的类型必需与指针声明的类型一样),如下:
int a=2; int* p=&a;
使用时,需要用 * 来给指针解引用,再进行修改,如下:
int a=2; //a=2; int* p=&a; *p=1; //a=1;
对于结构体(见下)指针,我们在获取或修改其中的元素时,应先解引用,再用 . 进行访问,或使用 -> 直接访问:
struct node{ int a,b,c; } x,y;
x=(1,2,3); y=(4,5,6);
node* p=&x; (*p)=y; //x=(4,5,6) (*p).a=7; //x=(7,5,6) p->b=10; //x=(7,10,6)
- 指针的遍历
由于数组的存储地址是连续的,所以如果使用指针对数组进行遍历,只需要通过枚举遍历即可。
int a[3]={1,1,1}; int* p=a;//p指向a[0] for(int i=1;i<3;i++){ p++; *p=(i+1); } //a={1,2,3}
对于一个多维数组,通常每个维度的最后一个元素的地址和下一维度的第一个元素的地址是连续的。也就是说,从内存的角度来看,一个 n 维数组 a[N][N][N]....[N],相当于一个长度为 Nn 的一维数组。
3) 结构体
结构体,是许多元素组合在一起的整体,一个结构体可以理解为是自定义变量类型,其中包含多个成员变量。
声明结构体时,先编写词语 struct ,接着写入结构体名称,随后是 { },括号中填写成员变量。括号结束后不要忘记加 ;
struct node{ //名为 node 的结构体 int a,b,c; //成员元素 a,b,c } x; //以 node 类型声明的变量 x; node y; //也可以这么写
对于这个结构体,其中包含三个 int 类型的成员变量,在使用 x 时,可以通过 . 来访问其中的成员变量。如:
x.a=10;
结构体可以适用于多种形式,如变量、数组、指针等。
4) 联合体
联合体是 2023 年新出的数据类型,其的声明和访问与结构体类似。
union node{ int a,b,c; } x; x.a=10;
但需要注意的是,联合体的成员变量是共用内存地址的,因此每次修改所有其他成员都会被覆盖。因此联合体的大小不超过其占用地址最多的成员变量的大小。
三、C++ 标准库
C++ 标准库简称 STL,主要包含一些容器及数据结构。常用的有:
1. 向量 vector。
2. 队列 queue。
3. 双端队列 deque。
4. 栈 stack。
5. 集合 set。
6. 映射 map。
1) 向量 vector
一个后端可高效增加元素的顺序表,也可以认为是动态大小的数组。
#include<vecotr> vector<int> v; v.push_back(1); //在 vector 的最后添加一个数据 v.pop_back() //去掉 vector 的最后一个数据 v.size() //当前 vector 的大小 v.resize() //改变当前 vector 的大小,如果比当前大就填充默认值 v.clear() //清空当前 vecotr v.erase() //删除当前指针指向的数据 v.begin() //返回当前第一个数据的指针 v.end() //返回当前最后一个数据的指针 v.rbegin() //返回反转 vector 后的第一个数据的指针 v.rend() //返回反转 vector 后的最后一个数据的指针
2) 单双端队列 queue & deque
queue:先进先出 (FIFO) 的容器。
deque:双端都可高效增加元素的顺序表。
#include<queue> queue<int> q; q.push(1); //在队列末尾添加一个数据 q.front(); //访问队列前端的数据 q.pop(); //弹出队列前端的数据 q.size(); //返回队列长度 q.empty(); //判断队列是否为空 #include<deque> deque<int> d; d.push_back(1); //在队列末尾添加一个数据 d.push_front(1); //在队列前端添加一个数据 d.front(); //访问前端的数据 d.back(); //访问末尾的数据 d.pop_front(); //弹出队列前端的数据 d.pop_back(); //弹出队列末尾的数据 d.clear(); //清空队列 d.size(); //返回队列长度 d.empty(); //判断队列是否为空 d.insert(); //在指定位置插入数据 d.erase(); //在指定位置删除数据
3) 栈 stack
stack:后进先出 (LIFO) 的容器。
#include<stack> stack<int> s; s.push(1); //在栈顶添加一个数据 s.top(); //访问栈顶的数据 s.pop(); //弹出栈顶的数据 s.empty(); //判断栈是否为空 s.size(); //返回栈内元素的数量
4) 集合 set
set:内部为红黑树,所有元素都先进行去重排序后存入。
#include<set> set<int> s; s.insert(1); //在集合中添加一个数据 s.find(1); //在集合中查找某一数据,并返回一个指针 s.erase(); //删除集合中某一数据 s.count(); //查询某一数据在集合中出现几次 s.begin(); //返回指向集合前端的迭代器 s.end(); //返回指向集合末尾的迭代器 s.rbegin(); //返回指向集合末尾的逆向迭代器 s.rend(); //返回指向集合前端的逆向迭代器 set<int>::iterator it=s.begin(); //迭代器 for(auto x:s){} //遍历,前提是c++11版
5) 映射 map
map:由键、值相对应组成的集合,可以通过键访问值,不可去重。
#include<map> map<int,int> m; m[x]=1; //赋值,x为键,1为值 m.clear(); //清空映射 m.erase(); //删除映射中某一数据 m.size();//返回映射的大小 m.begin(); //返回指向映射前端的迭代器 m.end(); //返回指向映射末尾的迭代器 m.rbegin(); //返回指向映射末尾的逆向迭代器 m.rend(); //返回指向映射前端的逆向迭代器 m.empty(); //判断映射是否为空
浙公网安备 33010602011771号