- 枚举enum , 共用体union
- this指针,迭代器iterator
- STL C++容器 顺序容器sequence container
- STL C++容器 关联容器associative container
- STL C++容器 容器适配器
顺序容器 { 向量 − v e c t o r 列表 − l i s t 双队列 − d e q u e 顺序容器 \begin{cases} 向量-vector\\ 列表-list\\ 双队列-deque \end{cases} 顺序容器⎩ ⎨ ⎧向量−vector列表−list双队列−deque
关联容器 { 映射 − m a p , m u l t i m a p 集合 − s e t , m u l t i s e t 关联容器 \begin{cases} 映射-map,multimap\\ 集合-set,multiset\\ \end{cases} 关联容器{映射−map,multimap集合−set,multiset
容器适配器 { 栈 − s t a c k 队列 − q u e u e 优先队列 − p r i o r i t y _ q u e u e 容器适配器 \begin{cases} 栈-stack\\ 队列-queue\\ 优先队列-priority\_queue \end{cases} 容器适配器⎩ ⎨ ⎧栈−stack队列−queue优先队列−priority_queue
stack filo ; queue fifo ; prioritoty_queue from max to min
✅enum、union
#include <iostream>
using namespace std;
//enum union
int main() {
/*enum*/
//enum Color{Blue,Red,Green,Yellow}a,b,c,d;
enum { Blue = 2, Red, Green, Yellow }a, b, c, d;
a = Blue; b = Red; c = Green; d = Yellow;
cout << a << "," << b << "," << c << "," << d << endl;
/*union*/
union data{
char a; char b;
};
data x;
x.a = 'M';
cout << x.a << endl;//M
x.b = 'x';
cout << x.a << endl;//x
system("pause");
return 0;
}
✅this指针
#include <iostream>
using namespace std;
//this 指针
class Box{
public:
Box(int l,int w,int h);
int V();
int Compare(Box box) { return this->V() > box.V(); }
private:
int length; int width; int height;
};
Box::Box(int l, int w, int h) {
length = l; width = w; height = h;
}
int Box::V() {
//return (length*width*height);
return(this->length*this->width*this->height);
//return((*this).length*(*this).width*(*this).height);//.优先级高于*,所以要()
}
int main() {
Box box1(3, 4, 5); Box box2(3, 2, 4);
//Box box2(3,5,6);
cout << "V_box1 = " << box1.V() << endl;
cout << "V_box2 = " << box2.V() << endl;
if (box1.Compare(box2)) {
//cout << "V_box1 > V_box2" << " " << box1.Compare(box2) << " " << box2.Compare(box1) << endl;
cout << "V_box1 > V_box2" << endl;
}
else if (box2.Compare(box1)) {
cout << "V_box1 < V_box2" << endl;
}
else cout << "V_box1 = V_box2" << endl;
system("pause");
return 0;
}
✅迭代器iterator
正序 iterator
逆序 reverse_iterator
vector<int>::iterator it;
for (it = a.begin(); it != a.end(); it++) {
cout << *it << " ";
}cout << endl;
✅vector
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
//vector
int main() {
vector<int> a(10, 1); vector<int> b(10, 0);
vector<vector<int>> c(3, vector<int>(4, 0));
vector<int>::iterator it;
//int i; // warning “<”: 有符号/无符号不匹配
unsigned int i; unsigned int m, n;
for (i = 0; i < a.size(); i++) { //initialize
cout << a[i] << " ";
}
//assign
cout << "please input: ";
cin >> a[2];
cin >> a[5];
cin >> a[8];
cout << "重新再赋值 ";
for (i = 0; i < a.size(); i++) {
cout << a[i] << " ";
}cout << endl;
//push_back pop_back
cout << "末尾加一个 ";
a.push_back(0);
for (i = 0; i < a.size(); i++) {
cout << a[i] << " ";
}cout << endl;
cout << "删最后一个 ";
a.pop_back();
for (i = 0; i < a.size(); i++) {
cout << a[i] << " ";
}cout << endl;
//insert
cout << "最前面插入 ";
a.insert(a.begin(), 0);
for (i = 0; i < a.size(); i++) {
cout << a[i] << " ";
}cout << endl;
//size
cout << "size = " << a.size()<< endl;
cout << "max size = " << a.max_size() << endl;
cout << "capacity = " << a.capacity() << endl;
//resize
cout << "改向量大小 ";
a.resize(20);
for (i = 0; i < a.size(); i++) {
cout << a[i] << " ";
}cout << endl;
// access with index
cout << "以下标访问 ";
for (i = 0; i < a.size(); i++) {
cout << a[i] << " ";
}cout << endl;
// access with iterator
cout << "迭代器访问 ";
for (it = a.begin(); it != a.end(); it++) {
cout << *it << " ";
}cout << endl;
// copy =;compare == != > < >= <=;sort;swap
cout << "大到小排序 ";
sort(a.begin(), a.end()); //#include <algorithm>
for (i = 0; i < a.size(); i++) {
cout << a[i] << " ";
}cout << endl;
cout << "交换向量值 ";
a.swap(b);
for (i = 0; i < a.size(); i++) {
cout << a[i] << " ";
}cout << endl;
//erase
cout << "删最前一个 ";
a.erase(a.begin());
for (i = 0; i < a.size(); i++) {
cout << a[i] << " ";
}cout << endl;
cout << "删指定范围 ";
//a.erase(a.begin(), a.end());//删全部
a.erase(a.begin() + 1, a.end());
for (i = 0; i < a.size(); i++) {
cout << a[i] << " ";
}cout << endl;
//clear
cout << "清空所有的 ";
a.clear();
for (i = 0; i < a.size(); i++) {
cout << a[i] << " ";
}cout << endl;
//empty
if (!(a.empty())) {
cout << "not empty" << endl;
}else cout << "empty" << endl;
//two-dimensional vector
cout << "input: " << endl;
cin >> c[0][1];
cin >> c[0][2];
cin >> c[0][0];
cout << "output:" << endl;
for (m = 0; m < c.size(); m++) {
for (n = 0; n < c[m].size(); n++) {
cout << c[m][n] << " ";
}cout << endl;
}
system("pause");
return 0;
}
✅list
#include <iostream>
#include <list>
#include <vector>
using namespace std;
//vector
int main() {
unsigned int i;
int a[5] = { 22,33,44,55,66 }; int b[5] = { 21,35,63 }; vector<int> v(2, 39);
//initialize lst2, Use the 5 value of array as the initial values for list2
list<int> lst1; list<int> lst2(a, a + 5); list<int> lst3(a, a + 5);
list<int>::iterator it; list<int>::iterator it1;
list<int>::reverse_iterator rit;
cout << "列表初始化 ";
for (i = 0; i <= 5; i++) { //initialize
lst1.push_back(i);
}
for (it = lst1.begin(); it != lst1.end(); ++it) {
cout << *it << " "; //0 1 2 3 4 5
}cout << endl;
//assign 指定 分配 委派 转让
cout << "委派列表值 ";
lst1.assign(5, 10);
for (it = lst1.begin(); it != lst1.end(); ++it) {
cout << *it << " ";//10 10 10 10 10
}cout << endl;
cout << "委派列表值 ";
lst1.assign(lst2.begin(), lst2.end());//copy lst2 to lst1
for (it = lst1.begin(); it != lst1.end(); ++it) {
cout << *it << " ";//22 33 44 55 66
}cout << endl;
cout << "添加新元素 ";//equivalent to replacing rather than appendding
lst1.assign(b, b + 3);//lst1 has been overwritten, and original one is no longer present
for (it = lst1.begin(); it != lst1.end(); ++it) {
cout << *it << " ";//21 35 63
}cout << endl;
//push_back pop_back push_front pop_front
cout << "末尾加数据 "; lst1.push_back(3);
for (it = lst1.begin(); it != lst1.end();++it) {
cout << *it << " ";//21 35 63 3
}cout << endl;
cout << "末尾删数据 "; lst1.pop_back();
for (it = lst1.begin(); it != lst1.end(); ++it) {
cout << *it << " ";//21 35 63
}cout << endl;
cout << "开头加数据 "; lst1.push_front(3);
for (it = lst1.begin(); it != lst1.end(); ++it) {
cout << *it << " ";//3 21 35 63
}cout << endl;
cout << "开头删数据 "; lst1.pop_front();
for (it = lst1.begin(); it != lst1.end(); ++it) {
cout << *it << " ";//21 35 63
}cout << endl;
//insert
cout << "插入新数据 ";
it1 = lst3.begin();
++it1;//pointer shift back 1
lst3.insert(it1, 9);//22 9 33 44 55 66
/*for (it1 = lst3.begin(); it1 != lst3.end(); ++it1) {
cout << *it1 << " ";//it1 will be moved to the end,impact output results
}cout << endl;*/
lst3.insert(it1, 2, 29);//22 9 29 29 33 44 55 66
lst3.insert(it1, v.begin(), v.end());//insert the value of the vector(39,39)
for (it1 = lst3.begin(); it1 != lst3.end(); ++it1) {
cout << *it1 << " ";//22 9 29 29 39 39 33 44 55 66
}cout << endl;
//size
cout << "size = " << lst1.size()<< endl;//size = 3
cout << "max size = " << lst1.max_size() << endl;//max size = 357913941
// access with iterator (positive sequence output)
cout << "迭代器正序 ";
for (it = lst2.begin(); it != lst2.end(); ++it) {
cout << *it << " ";//22 33 44 55 66
}cout << endl;
// access with iterator (reverse sequence output)
cout << "迭代器逆序 ";
for (rit = lst2.rbegin(); rit != lst2.rend(); ++rit) {
cout << *rit << " ";//66 55 44 33 22
}cout << endl;
//erase
cout << "删除指定位 ";
it1 = lst3.begin();
advance(it1, 6);//pointer shift back 6
it1 = lst3.erase(it1);
for (it1 = lst3.begin(); it1 != lst3.end(); ++it1) {
cout << *it1 << " ";//22 9 29 29 39 39 44 55 66
}cout << endl;
//a.erase(a.begin(), a.end());//删全部
cout << "删除所有的 ";
lst3.erase(lst3.begin(), lst3.end());//erase all = clear
for (it1 = lst3.begin(); it1 != lst3.end(); ++it1) {
cout << *it1 << " ";
}cout << endl;
system("pause");
return 0;
}
✅deque
#include <iostream>
#include <deque>
#include <algorithm>
using namespace std;
//deque
void print(int num) {
cout << num << " ";
}
int main() {
deque<int> v;
deque<int>::iterator iv;
cout << "deque\n";
//assign
v.assign(5, 2);// assign a value of 2,
for_each(v.begin(), v.end(), print);
cout << "\t\tsize = " << v.size();
//push_front push_back
v.push_front(0);///push_front
for (int i = 1; i <= 5; i++) {///push_back
v.push_back(i);
}cout << endl;
for_each(v.begin(), v.end(), print);
cout << "\tsize = " << v.size()<<endl;
//insert
v.insert(v.begin() + 3, 9);//end() can also be used
for_each(v.begin(), v.end(), print);// traversal
cout << endl;
for_each(v.rbegin(), v.rend(), print);// reverse traversal
cout << endl;
for (iv = v.begin(); iv != v.end(); ++iv) { // iterator traversal
cout << *iv << " ";
}cout << endl;
//erase
v.erase(v.begin() + 3);//erase 4,begin erase 1...
for_each(v.begin(), v.end(), print); cout << endl;
v.erase(v.begin() + 6, v.begin() + 7);//erase 7
for_each(v.begin(), v.end(), print); cout << endl;
//pop_front pop_back
v.pop_front();
v.pop_back();
for_each(v.begin(), v.end(), print); cout << endl;
//front back
cout << "front = " << v.front();
cout << "back = " << v.back() << endl;
//clear
v.clear();
for_each(v.begin(), v.end(), print);
cout << "size = " << v.size() << endl;
system("pause");
return 0;
}
/*
deque
2 2 2 2 2 size = 5
0 2 2 2 2 2 1 2 3 4 5 size = 11
0 2 2 9 2 2 2 1 2 3 4 5
5 4 3 2 1 2 2 2 9 2 2 0
0 2 2 9 2 2 2 1 2 3 4 5
0 2 2 2 2 2 1 2 3 4 5
0 2 2 2 2 2 2 3 4 5
2 2 2 2 2 2 3 4
front = 2back = 4
size = 0
请按任意键继续. . .
*/
⭕map
#include <iostream>
#include <map>
#include <string>
using namespace std;
//map
int main() {
map<int,string> m;
map<int, string>::iterator it;
map<int, string>::reverse_iterator rit;
///insert pair
//assign
m.insert(pair<int, string>(1, "one"));
m.insert(pair<int, string>(2, "two"));
m.insert(pair<int, string>(3, "three"));
for (rit = m.rbegin(); rit != m.rend(); rit++) {///push_back
cout << rit->first << " " << rit->second << endl;
}cout << endl;
/*----------
3 three
2 two
1 one
-----------*/
///insert value_type
cout << endl;
m.insert(map<int, string>::value_type(4, ",,,"));
m.insert(map<int, string>::value_type(5, "..."));
for (it = m.begin(); it != m.end(); it++) {
cout << it->first << " " << it->second << endl;
}cout << endl;
/*----------
1 one
2 two
3 three
4 ,,,
5 ...
-----------*/
///return mapped value
cout << endl;
m[6] = "cat";
m[7] = "fish";
m[8] = "bear";
cout << "m[2] value = " << m[2] << "\tm[8] value = " << m[8] << endl;
///size
cout << "size = " << m.size() << endl;
///count
cout << "m[9] " << m.count(9) << "\tm[1] " << m.count(1) << endl;
/*----------
m[2] value = two m[8] value = bear
size = 8
m[9] 0 m[1] 1
-----------*/
///find
///erase
cout << endl;
m.erase(2);
for (it = m.begin(); it != m.end(); it++) {
cout << it->first << " " << it->second << endl;
//cout << (*it).first << " " << (*it).second << endl;
}
/*----------
1 one
3 three
4 ,,,
5 ...
6 cat
7 fish
8 bear
-----------*/
system("pause");
return 0;
}
⭕set
#include <iostream>
#include <set>
#include <vector>
using namespace std;
//set
int main() {
vector<int> ivec;
for (vector<int>::size_type i=0; i != 10; ++i) {
ivec.push_back(i);
ivec.push_back(i);
}
set<int> iset(ivec.begin(), ivec.end());
cout << ivec.size() << endl;//20
cout << iset.size() << endl;//10
//insert find count
system("pause");
return 0;
}
⭕stack、queue、priority_queue
#include <iostream>
#include <stack>
#include <queue>
using namespace std;
int main() {
//stack
///push() pop() empty() size() top()
stack<int> stk;
stk.push(25); stk.push(17); stk.push(4); stk.push(100); stk.push(45);
cout << "size of stack = " << stk.size() << endl;
while (stk.size() != 0) {
cout << "top value = " << stk.top() << endl;
stk.pop();///pop it
}
if (stk.empty()) {
cout << "stack is empty" << endl;
}
cout << endl;
//queue
///push() pop() front() back() empty() size() top()
queue<int> q;
/*push (25,17,4,100,45) into queue*/
q.push(25); q.push(17); q.push(4); q.push(100); q.push(45);
cout << "size of queue = " << q.size() << endl;
cout << "front,back = " << q.front() << "," << q.back() << endl;
while (q.size() != 0) {
cout << "top value = " << q.front() << endl;
q.pop();//pop it
}
if (q.empty()) {
cout << "queue is empty" << endl;
}
cout << endl;
//priority_queue
///push() pop() empty() size() top()
priority_queue<int> q1;
/*push (25,17,4,100,45) into priority_queue*/
q1.push(25); q1.push(17); q1.push(4); q1.push(100); q1.push(45);
cout << "size of priority_queue = " << q1.size() << endl;
while (q1.size() != 0) {
cout << "top value = " << q1.top() << endl;
q1.pop();//pop it
}
if (q1.empty()) {
cout << "priority_queue is empty" << endl;
}
system("pause");
return 0;
}
⌨ STL eg
#include <iostream>
#include <vector>
#include <string>
#include<algorithm>
using namespace std;
struct Person {
char name[10];
int age;
};
bool comp(const Person &a, const Person &b) {
return a.age < b.age;
}
int main() {
vector<Person> v_per;
vector<Person>::iterator it;
int n = 5;
while (n--) {
Person person;
string name;
int age;
cin >> name >> age;
strcpy_s(person.name, name.c_str());
person.age = age;
v_per.push_back(person);
}
cout << "before: " << endl;
for (it = v_per.begin(); it != v_per.end(); it++) {
cout << "name: " << it->name << "\tage: " << it->age << endl;
}
sort(v_per.begin(), v_per.end(), comp);
cout << "after: " << endl; //sort according age
for (it = v_per.begin(); it != v_per.end(); it++) {
cout << "name: " << it->name << "\tage: " << it->age << endl;
}
system("pause");
return 0;
}
error 未定义标识符
C++文档注释
🤖在 C++ 中,/// 并不是一个特定的语法结构或运算符,而是一种单行注释的表示方法。
C++ 中有两种主要的注释方式:
1.单行注释: 使用 // 开始,直到行末。例如:
// 这是单行注释
2.多行注释: 使用 /* 开始,*/ 结束,可以跨越多行。例如:
/*
这是
多行
注释
*/
在这两种注释方式中,/// 并没有特殊的含义,它只是单行注释 // 的一个变体。在某些编码规范或项目中,程序员可能选择使用 /// 作为单行注释的一种风格,以便在代码中更容易识别单行注释。但是,它的使用与 // 是等效的,不会引入任何不同的行为。
/// <summary>description</summary>
🤖 在 C++ 中,<summary> 和 </summary> 并不是标准的注释标记。它们更常见于文档生成工具,例如 Doxygen。
Doxygen 是一种广泛用于生成代码文档的工具,它可以从源代码中提取注释,并生成格式化的文档。在 Doxygen 中,可以使用 /** … */ 形式的注释块,并在其中使用一些特殊标记来提供更丰富的文档信息。<summary> 是其中之一,用于提供关于函数或类的简要描述。
例如:
// xml_summary_tag.cpp
// compile with: /LD /clr /doc
// post-build command: xdcmake xml_summary_tag.dll
/// Text for class MyClass.
public ref class MyClass {
public:
/// <summary>MyMethod is a method in the MyClass class.
/// <para>Here's how you could make a second paragraph in a description. <see cref="System::Console::WriteLine"/> for information about output statements.</para>
/// <seealso cref="MyClass::MyMethod2"/>
/// </summary>
void MyMethod(int Int1) {}
/// text
void MyMethod2() {}
};
/*
* @brief 这是一个演示类的简要描述.
*/
class DemoClass {
public:
/* @brief 这是一个演示函数的简要描述. *
* 具体的函数实现和细节说明可以在这里添加. *
* @param arg1 参数1的说明. *
* @param arg2 参数2的说明. *
* @return 返回值的说明. */
int demoFunction(int arg1, int arg2);
};
在上述例子中,<summary> 标记用于提供类和函数的简要描述,而 Doxygen 的其他标记如 @brief、@param、@return 等则用于提供更详细的说明。
需要注意的是,这些标记并非标准 C++ 注释,而是 Doxygen 特有的标记,需要通过运行 Doxygen 工具来生成文档。如果你的项目中没有使用 Doxygen 或其他类似的文档生成工具,这些标记在编译时并不会被视为注释,不会影响程序的行为。
❓c++中使用迭代器访问向量优缺是什么
🤖
在 C++ 中,使用迭代器(iterator)访问向量(vector)具有一些优点和缺点。
优点:
1.通用性和灵活性: 迭代器提供了一种通用的方法来访问容器中的元素,不仅限于向量。同样的迭代器接口可以用于访问其他标准容器,如列表(list)、映射(map)等。
2.抽象性: 迭代器提供了一种抽象层,隐藏了底层数据结构的细节。这意味着,无论是使用数组还是其他类型的容器,迭代器都提供了一致的接口。
3.支持各种操作: 迭代器可以执行诸如遍历、查找、插入和删除等操作。它们可以用于执行循环,访问容器的每个元素,或者在特定条件下搜索元素。
缺点:
4.性能开销: 对于某些类型的迭代器,特别是在一些编译器实现中,迭代器可能会带来一些性能开销。这可能是由于迭代器的抽象性以及额外的间接性质造成的。
5.指针失效问题: 在某些情况下,在修改容器时(例如,插入或删除元素),迭代器可能会失效。这意味着对迭代器的使用可能会导致未定义行为或错误。这需要开发者特别注意避免在容器改变的情况下继续使用失效的迭代器。
❓在c++中句柄是什么意思
🤖在 C++ 中,句柄(Handle)是一个抽象的概念,通常用于引用或标识对象、资源或数据结构的标识符。句柄本身不一定是实际的对象或资源,而是对它们的引用或间接访问。
在操作系统或特定库中,句柄可以用于管理资源的访问。例如,在 Windows 编程中,句柄通常用于引用图形界面中的窗口、设备上下文、文件、内核对象等。
句柄可以是指向数据结构的指针,也可以是数字或特殊值,这取决于操作系统或库的设计。
在 C++ 中,句柄的使用可能需要使用特定的库或API,并且通常需要严格的管理,以确保正确释放资源,避免内存泄漏或资源泄露。
例如,在 Windows 编程中,可以使用 HWND 类型作为窗口句柄的标识符:
#include <windows.h>
int main() {
// 创建一个窗口句柄
HWND hWnd = CreateWindowEx(
0, // 扩展样式
"MyWindowClass", // 窗口类名称
"My Window", // 窗口标题
WS_OVERLAPPEDWINDOW, // 窗口样式
CW_USEDEFAULT, CW_USEDEFAULT, // 窗口位置
800, 600, // 窗口大小
NULL, // 父窗口
NULL, // 菜单句柄
NULL, // 应用程序实例句柄
NULL // 附加参数
);
// 对窗口句柄进行操作
// ...
return 0;
}
在这个示例中,HWND 就是窗口句柄的类型,用于标识窗口对象,并且在 Windows 编程中经常被使用。使用窗口句柄可以对窗口进行操作、发送消息、接收事件等。
❓include"iostream.h"
与#include<iostream>
区别
🤖在C++中,#include 指令用于包含头文件,而头文件的命名方式可能受到不同编译器和标准的影响。
#include"iostream.h";
这种形式使用双引号将头文件名括起来,通常表示该头文件在当前源文件所在目录中查找。这是在旧版本的C++标准和一些旧的编译器中常见的写法。
在一些早期的C++编译器(如Turbo C++)和C编译器中,标准C++库的头文件采用了 .h 的扩展名,例如 iostream.h。
#include <iostream>;
这种形式使用尖括号将头文件名括起来,表示该头文件在标准系统目录中查找。这是符合现代C++标准的写法。
标准C++库的头文件不再带有 .h 扩展名。因此,标准输入输出流的头文件应该写成 #include <iostream>。
在现代C++中,推荐使用第二种写法,即使用尖括号括起头文件名。这种写法更符合C++标准,适用于现代的编译器和开发环境。如果你使用的是较新的C++编译器,应该避免使用 .h 扩展名的头文件,而改用不带扩展名的形式。