指针与数组
p是指针,也可以是数组。
int a[3] = {1, 2, 3};
int* p = a;
p[2]
和 *(p + 2)
是等价的。
a[2]
与 *(a + 2)
不等价。(a的类型为int[3]
,+2之后会偏移6个int的长度)
偏移量取决于指针/数组的类型。
动态内存分配
int* p = new int(1234);
/* ... */
delete p;
申请一块int
大小的空间,将空间值初始化为1234
,声明int
型指针p
存储该空间地址。
(等号右侧的int
为构造器)
List initialization
struct ThreeInt {
int a;
int b;
int c;
};
int main() {
ThreeInt* p = new ThreeInt{1, 2, 3};
/* ... */
delete p;
}
二维数组的技巧
可以声明一个连续的一维数组。
int* a = new int[N * M];
访问时访问:r*M+c
。
另一种方式:
int main() {
int(*a)[5] = new int[5][5];
int* p = a[2]; // 获得数组的第3行(row)的首地址
a[2][1] = 1;
delete[] a;
}
文件操作
OI官方推荐freopen,
freopen("data.in", "r", stdin);
freopen("data.out", "w", stdout);
然后正常操作就可以了。
样例:
#include <cstdio>
#include <iostream>
int main(void) {
freopen("data.in", "r", stdin);
freopen("data.out", "w", stdout);
/*
中间的代码不需要改变,直接使用 cin 和 cout 即可
*/
fclose(stdin);
fclose(stdout);
return 0;
}
STL 容器
摘自:简书 - C++进阶-STL容器,你看我就够了(作者:岁与禾)
序列式容器
vector
vector有4种方式初始化,有直接初始化,也要通过拷贝构造函数初始化。
int main(int argc, const char * argv[]) {
//直接构造函数初始化
vector<int> v1;
v1.push_back(1);
v1.push_back(2);
v1.push_back(3);
v1.push_back(4);
//通过拷贝构造函数初始化
vector<int> v2 = v1;
//使用部分元素来构造
vector<int> v3(v1.begin(), v1.begin() + 1);
vector<int> v4(v1.begin(), v1.end());
//存放三个元素,每个元素都是9
vector<int> v5(3,9);
return 0;
}
基本用法:
int main(int argc, const char * argv[]) {
//定义一个vector容器
vector<int> v1;
//插入元素(尾部插入)
v1.push_back(1);
v1.push_back(2);
v1.push_back(3);
//迭代器遍历打印
for (vector<int>::iterator it = v1.begin(); it != v1.end(); it++) {
cout << *it << " ";
}
cout << endl;
//修改头部元素的值(front()返回是引用,可以当左值)
v1.front() = 44;
//输出头部元素
cout<< "头部元素:" << v1.front() << endl;
//修改尾部的值(back()返回是引用,可以当左值)
v1.back() = 99;
//输出尾部元素
cout << "尾部元素" << v1.back() <<endl;
//删除元素(从尾部删除)
v1.pop_back();
//迭代器遍历打印
for (vector<int>::iterator it = v1.begin(); it != v1.end(); it++) {
cout << *it << " ";
}
cout << endl;
return 0;
}
遍历:at或[]
int main(int argc, const char * argv[]) {
//创建vector
vector<int> v1;
//插入元素
for (int i = 0; i < 10; i++) {
v1.push_back(i);
}
//遍历-[]取值
for (int i = 0; i < v1.size(); i++) {
cout << v1[i] << " ";
}
cout << endl;
//遍历-at取值
for (int i = 0; i < v1.size(); i++) {
cout << v1.at(i) << " ";
}
cout << endl;
//遍历-迭代器遍历
for (vector<int>::iterator it = v1.begin(); it != v1.end(); it++) {
cout << *it << " ";
}
cout << endl;
//遍历-迭代器逆向遍历
for (vector<int>::reverse_iterator it = v1.rbegin(); it != v1.rend(); it++) {
cout << *it << " ";
}
cout << endl;
//测试越界
cout << "[]越界:" << v1[20] << endl; //不会抛出异常,可能会崩溃,可能会乱码
cout << "at越界:" << v1.at(20) << endl; //会抛出异常,需要捕获异常
return 0;
}
插入元素:insert
int main(int argc, const char * argv[]) {
//初始化vector对象
vector<int> v1(10);
//在指定的位置插入元素10的拷贝
v1.insert(v1.begin() + 3, 10);
//在指定的位置插入3个元素11的拷贝
v1.insert(v1.begin(), 3, 11);
//遍历
for (vector<int>::iterator it = v1.begin(); it != v1.end(); it++) {
cout << *it << " ";
}
cout << endl;
return 0;
}
array
// 1. 创建空array,长度为3; 常数复杂度
std::array<int, 3> v0;
// 2. 用指定常数创建array; 常数复杂度
std::array<int, 3> v1{1, 2, 3};
v0.fill(1); // 填充数组
// 访问数组
for (int i = 0; i != arr.size(); i++)
cout << arr.at(i) << " ";
stack
int main(int argc, const char * argv[]) {
//定义stack对象
stack<int> s1;
//入栈
s1.push(1);
s1.push(2);
s1.push(3);
s1.push(4);
//打印栈顶元素,并出栈
while (!s1.empty()) {
//取出栈顶元素
cout << "当前栈顶元素" << s1.top() << endl;
//获取栈的大小
cout << "当前栈的大小" << s1.size() << endl;
//出栈
s1.pop();
}
return 0;
}
queue
#include <queue>
void main()
{
queue<int> q;
q.push(1);
q.push(2);
q.push(3);
cout << "对头元素" << q.front() <<endl;
cout << "队列的大小 " << q.size() <<endl;
while (!q.empty()) {
int tmp = q.front();
cout << tmp << " ";
q.pop();
}
}
class Teacher
{
public:
int age;
char name[32];
void printT()
{
cout << "age :" << age <<endl;
}
}
void main()
{
Teacher t1,t2,t3;
t1.age = 31;
t2.age = 32;
t3.age = 33;
queue<Teacher > q;
q.push(t1);
q.push(t2);
q.push(t3);
while (!q.empty()) {
Teacher tmp = q.front();
tmp.printT();
q.pop();
}
}
C++ 进阶
目前看到C++进阶,先爬去看算法竞赛入门经典。