C/C++基础语法
C/C++基础语法
文章目录
- C/C++基础语法
- 头文件
- 经典问题
- 链表
- 链表基础操作
- 秒数转换
- 闰年
- 斐波那契数列
- 打印n阶菱形
- 曼哈顿距离
- 菱形图案的定义
- 大数计算
- 输入输出
- 格式化输入输出
- `getline()`函数解决`cin`只读入一个单词的问题
- fgets读入整行
- 输出字符数组(两种方式puts和printf)
- 运算符
- 赋值运算符
- Switch
- 循环
- 处理未知数量输入的几种常见方法
- for-each
- 字符
- 字符数组的常用操作
- 字符串String
- 基本概念
- 其他数据类型转变为字符串`to_string()`
- 字符串连接
- 字符串判空
- 字符串长度
- 字符串输入输出
- string的比较:
- 为string对象赋值:
- 两个string对象相加:
- 字面值和string对象相加:
- 遍历数组
- 数组
- 初始化memset
- 函数原型
- 参数
- 返回值
- 使用示例
- 注意事项
- 数组复制memcpy
- 函数原型
- 参数
- 返回值
- 使用示例
- 注意事项
- 函数
- 多维数组形参的写法
- 类与结构体
- 类与结构体的定义与使用
- 构造函数
- 指针和引用
- STL
参考资料:
- AcWing
- https://www.w3schools.com/cpp/
- https://cui-jiacai.gitbook.io/c+±stl-tutorial/
- https://www.youtube.com/watch?v=RRVYpIET_RU
- https://takeuforward.org/c/c-stl-tutorial-most-frequent-used-stl-containers/
头文件
#include <cmath>
经典问题
链表
#include <iostream>using namespace std;struct Node
{int val;Node *next;Node(int _val) : val(_val), next(NULL) {} // 空指针
};int main()
{Node node = Node(1); // 定义了一个node类型的变量Node *p = &node;//定义完之后用指针指向
}
C++中可以直接生成一个结构体,然后把这个结构体放到指针p中
Node *p = new Node(1); // 我定义了一个Node类型的变量,他的返回值是这个变量的地址
#include <iostream>using namespace std;struct Node
{int val;Node *next;Node(int _val) : val(_val), next(NULL) {} // 空指针
};int main()
{Node *p = new Node(1); // 我定义了一个Node类型的变量,他的返回值是这个变量的地址auto q = new Node(2);p->next=q;
}
头节点:第一个节点的地址,而不是他的值
链表基础操作
遍历,头插,删除
运行结果:
秒数转换
输入一个整数,表示时间,单位是秒。输出一个字符串,用”时:分:秒”的形式表示这个时间。
#include <iostream>
#include <cstdio>using namespace std;int main()
{int t;cin >> t;int hours = t / 3600;int minutes = t % 3600 / 60;int seconds = t % 60;printf("%d:%d:%d\n", hours, minutes, seconds);return 0;
}
int hours = t / 3600;
计算总秒数 t 包含多少完整的小时。因为1小时 = 3600秒,所以使用整数除法 t / 3600 可以得到完整小时数。整数除法的结果是去掉小数部分,仅保留整数部分。int minutes = t % 3600 / 60;
首先,t % 3600 计算出除去完整小时后剩余的秒数。然后,将这个剩余的秒数除以60(因为1分钟 = 60秒)得到完整分钟数。这里也使用了整数除法,因此结果是剩余秒数中包含的完整分钟数。int seconds = t % 60;
使用取模运算 t % 60 计算出除去完整分钟后剩余的秒数。因为1分钟是60秒,所以这个操作会得到小于60的秒数,即最后剩余的秒数部分。
闰年
判断闰年。闰年有两种情况:
(1) 能被100整除时,必须能被400整除;
(2) 不能被100整除时,被4整除即可。
- 输入一个年份,如果是闰年输出yes,否则输出no。
#include <iostream>
#include <cstdio>using namespace std;int main()
{int year;cin >> year;if (year % 100 == 0){if (year % 400 == 0) cout << "yes" << endl;else cout << "no" << endl;}else{if (year % 4 == 0) cout << "yes" << endl;else cout << "no" << endl;}return 0;
}
- 用一条if语句,判断闰年。
#include <iostream>
#include <cstdio>using namespace std;int main()
{int year;cin >> year;if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0)cout << "yes" << endl;elsecout << "no" << endl;return 0;
}
斐波那契数列
求斐波那契数列的第n项。f(1) = 1, f(2) = 1, f(3) = 2, f(n) = f(n-1) + f(n-2)。
#include <iostream>using namespace std;int main()
{int n;cin >> n;int a = 1, b = 1, i = 1;while (i < n){int c = a + b;a = b;b = c;i ++ ;}cout << a << endl;return 0;
}
打印n阶菱形
输入一个n,打印n阶菱形。n是奇数。
#include <iostream>using namespace std;int main()
{int n;cin >> n;int cx = n / 2, cy = n / 2;for (int i = 0; i < n; i ++ ){for (int j = 0; j < n; j ++ )if (abs(i - cx) + abs(j - cy) <= n / 2)cout << '*';else cout << ' ';cout << endl;}return 0;
}
曼哈顿距离
理解 abs(i - cx) + abs(j - cy) <= n / 2
这个条件的关键在于理解曼哈顿距离(Manhattan Distance)的概念,以及如何通过这个距离来定义一个菱形(或者说是正方形对角线方向的正方形)图案。
曼哈顿距离是在格点坐标系中,两点在标准的直角坐标系中的绝对轴距总和(只能横行走和纵向走,走到中心点要几步)。对于任意两点 (x1, y1)
和 (x2, y2)
,它们的曼哈顿距离是 |x1 - x2| + |y1 - y2|
。
在这个程序中,(i, j)
表示当前遍历到的网格点的坐标,(cx, cy)
是图案中心点的坐标。abs(i - cx) + abs(j - cy)
计算的就是当前点 (i, j)
到中心点 (cx, cy)
的曼哈顿距离。
菱形图案的定义
这个条件 abs(i - cx) + abs(j - cy) <= n / 2
用于判断当前点是否在菱形图案内部(包括边界)。这里的 n / 2
实际上定义了菱形的“半径”,即从中心点到边界的最大曼哈顿距离。
- 当
abs(i - cx) + abs(j - cy)
的值小于或等于n / 2
时,这意味着当前点(i, j)
距离中心点的曼哈顿距离在菱形的半径范围内,因此,它位于菱形内部或边界上,程序应该在这个位置打印一个星号*
。 - 当这个距离大于
n / 2
时,当前点(i, j)
在菱形外部,程序在这个位置打印一个空格
-
大数计算
计算 2 的 N 次方。N≤10000
#include <iostream>
#include <algorithm>using namespace std;int main()
{int a[10000], size = 1, n;a[0] = 1;cin >> n;while (n -- ){int t = 0;for (int i = 0; i < size; i ++ ){t += a[i] * 2;a[i] = t % 10;t /= 10;}if (t) a[size ++ ] = t;}for (int i = size - 1; i >= 0; i -- ) cout << a[i];cout << endl;return 0;
}
这段代码是一个计算2
的N
次方的程序,特别适用于处理大数运算,即当N
很大时,直接使用常规数据类型(如int
、long
)无法存储结果的情况。这里N
可以达到10000
。程序通过模拟手工乘法的方式来计算结果,将每一位数字存储在一个数组a
中,数组的每个元素代表结果数的一位,a[0]
是结果的最低位,a[size-1]
是结果的最高位。
下面是代码的详细解释:
-
初始化:
int a[10000]
:定义一个数组a
,用于存储计算过程中的每位数字。size = 1
:初始化结果数字的大小为1,因为2
的0
次方等于1
,所以起始时数组只有一位数字1
。a[0] = 1
:将结果的最低位初始化为1
。
-
读取输入:
cin >> n
:从标准输入读取N
的值。
-
计算
2
的N
次方:while (n -- )
:循环N
次,每次循环相当于将当前结果乘以2
。- 在每次循环中,使用变量
t
来存储进位,初始时进位为0
。 for (int i = 0; i < size; i ++ )
:遍历数组的每一位,模拟乘法运算。t += a[i] * 2
:当前位乘以2
加上前一位的进位(如果有)。a[i] = t % 10
:更新当前位的值为新计算结果的个位数。t /= 10
:计算新的进位值。- 如果最后一位运算完后还有进位(
t
不为0
),则将这个进位作为新的最高位添加到数组的末尾,并增加size
。
-
输出结果:
- 由于数组中存储的是倒序的结果(即最低位在数组的开始位置),因此输出时需要从
size - 1
开始倒序遍历数组。 for (int i = size - 1; i >= 0; i -- ) cout << a[i];
:倒序输出数组的每一位,即输出计算得到的2
的N
次方的结果。cout << endl;
:在结果后输出换行符。
- 由于数组中存储的是倒序的结果(即最低位在数组的开始位置),因此输出时需要从
输入输出
格式化输入输出
#include <iostream>
#include <cstdio>using namespace std;int main()
{float b = 3.12345678;double c = 3.12345678;printf("%.4f\n", b);printf("%.3lf\n", c);printf("%5d\n", a);printf("%8.4f\n", b);printf("%7.3lf\n", c);printf("%-5d!\n", a);printf("%-8.4f!\n", b); // 如果整个数字(包括小数点和小数部分)不足8个字符,则在右侧用空格填充,实现左对齐。printf("%-7.3lf!\n", c);printf("%05d\n", a);printf("%08.4f\n", b);printf("%07.3lf\n", c);return 0;
}
- float, double等输出保留若干位小数时用:
%.4f
,%.3lf
%8.3f
, 表示这个浮点数的最小宽度为8,保留3位小数,当宽度不足时在前面补空格。%-8.3f
,表示最小宽度为8,保留3位小数,当宽度不足时在后面补上空格%08.3f
, 表示最小宽度为8,保留3位小数,当宽度不足时在前面补上0
getline()
函数解决cin
只读入一个单词的问题
cin
将空格(空格、制表符等)视为终止字符,这意味着它只能存储单个单词(即使您键入许多单词)
在处理字符串时,我们经常使用 getline() 函数来读取一行文本。它以 cin 作为第一个参数,字符串变量作为第二个参数:
string fullName;
cout << "Type your full name: ";
getline (cin, fullName);
cout << "Your name is: " << fullName;
或
char s[100];cin.getline(s, 100); // 100是这一行最多读多少个字符cout << s << endl;return 0;
fgets读入整行
如果题目没有超时,用getline比较好;如果输入量比较大用fgets比较好
char s[100];fgets(s, 100, stdin);//100是最多读入多少个字符cout << s << endl;
输出字符数组(两种方式puts和printf)
char s[100];cin.getline(s, 100); // 100是这一行最多读多少个字符puts(s);printf("%s\n",s);//这两种输出方式等价return 0;
运算符
赋值运算符
这些赋值运算符是C++(以及C和其他语言)中的复合赋值运算符,它们将算术或位运算和赋值操作结合在一起。每个运算符的作用如下:
&=
(按位与赋值运算符)
- 语法:
x &= 3
- 等效于:
x = x & 3
- 作用: 将
x
与3
进行按位与操作,然后将结果赋值给x
。按位与操作对应位都为1时结果为1,否则为0。
|=
(按位或赋值运算符)
- 语法:
x |= 3
- 等效于:
x = x | 3
- 作用: 将
x
与3
进行按位或操作,然后将结果赋值给x
。按位或操作对应位有一个为1时结果为1,都为0时结果为0。
^=
(按位异或赋值运算符)
- 语法:
x ^= 3
- 等效于:
x = x ^ 3
- 作用: 将
x
与3
进行按位异或操作,然后将结果赋值给x
。按位异或操作对应位不同为1,相同为0。
>>=
(右移赋值运算符)
- 语法:
x >>= 3
- 等效于:
x = x >> 3
- 作用: 将
x
的二进制表示向右移动3
位,然后将结果赋值给x
。右移操作会将高位丢弃,对于无符号数,低位补0;对于有符号数,低位补充依赖于具体实现(通常是补符号位,即算术右移)。
<<=
(左移赋值运算符)
- 语法:
x <<= 3
- 等效于:
x = x << 3
- 作用: 将
x
的二进制表示向左移动3
位,然后将结果赋值给x
。左移操作会在低位补0,高位丢弃,相当于将x
乘以2
的移动位数次方(这里是2^3
或8
)。
二进制位移操作解释
Switch
int day = 4;
switch (day) {case 1:cout << "Monday";break;case 2:cout << "Tuesday";break;case 3:cout << "Wednesday";break;case 4:cout << "Thursday";break;case 5:cout << "Friday";break;case 6:cout << "Saturday";break;case 7:cout << "Sunday";break;
}
// Outputs "Thursday" (day 4)
循环
处理未知数量输入的几种常见方法
-
while(cin >> x)
在C++中,cin >> x
尝试从标准输入(通常是键盘输入或重定向的文件输入)读取一个值到变量x
中。如果读取成功,表达式的值为true
;如果遇到输入结束(如文件结束或遇到不匹配类型的输入),表达式的值为false
。因此,while(cin >> x)
循环会持续读取输入直到遇到输入结束。 -
while(scanf("%d", &x) != -1)
和while(~scanf("%d", &x))
在C语言中,scanf("%d", &x)
尝试从标准输入读取一个整数到变量x
中。scanf
函数返回成功读取的项目数量。如果读取成功,返回1
;如果遇到输入结束(EOF),返回-1
。
while(scanf("%d", &x) != -1)
循环会持续读取输入,直到scanf
返回-1
,即遇到输入结束。while(~scanf("%d", &x))
利用了位运算符~
(按位取反)。在大多数系统上,EOF
(即-1
)按位取反后的结果是0
,而0
是逻辑假。因此,这个循环同样会持续读取输入,直到遇到输入结束。这是一种更为简洁的写法。
while(cin >> x && x)
和while(cin >> x, x)
这两种形式都用于处理当读入的最后一个值为0
且这个0
不需要处理的情况。
while(cin >> x && x)
循环会持续读取并处理非零的输入。如果x
为0
或遇到输入结束,循环停止。while(cin >> x, x)
使用了逗号运算符,该运算符执行其两边的表达式,并返回右侧表达式的结果。这里先尝试从输入读取一个值到x
,然后通过逗号运算符返回x
的值作为while
循环的条件。这个用法较为少见,且可能引起混淆,其效果与while(cin >> x && x)
相同。
以上这些方法提供了在未知数量输入的情况下从标准输入读取数据的有效手段,以及如何根据特定条件(如输入的值为 0
)结束输入的方式。
for-each
“for-each 循环”(在 C++ 版本 11 (2011) 中引入,专门用于循环数组(或其他数据集合)中的元素
int myNumbers[5] = {10, 20, 30, 40, 50};
for (int i : myNumbers) {cout << i << "\n";
}
字符
常用 ASCIl 值:‘A’-Z’是65~90, ‘a’-z’是97-182,‘0’-'9’是 48-57。
宇符可以参与运算,运算时会将其当做整数
字符数组的常用操作
下面几个函数需要引入头文件:
#include <string.h>//或者
#include <cstring>
strlen(str)
,求字符串的长度(\0
不计入其中)时间复杂度是 O ( n ) O(n) O(n)strcmp(a, b)
,比较两个字符串的大小,a < b返回-1,a == b返回0,a > b返回1。这里的比较方式是字典序!strcpy(a, b)
,将字符串b复制给从a开始的字符数组。
字符串String
基本概念
可变长的字符序列,比字符数组更加好用。需要引入头文件:
#include <string>
- 定义和初始化:
#include <iostream>
#include <string>using namespace std;int main()
{string s1; // 默认初始化,s1是一个空字符串string s2 = s1; // s2是s1的副本,注意s2只是与s1的值相同,并不指向同一段地址string s3 = "hiya"; // s3是该字符串字面值的副本string s4(10, 'c'); // s4的内容是 "cccccccccc"return 0;
}
其他数据类型转变为字符串to_string()
int c = 10;string num = to_string(c);cout << num << endl;
字符串连接
使用+
号或者append()
string firstName = "John";
string lastName = "Doe";
string fullName = firstName + " " + lastName;
fullName = firstName.append(lastName);
cout << fullName;
字符串判空
string s1, s2 = "abc";cout << s1.empty() << endl;//输出1cout << s2.empty() << endl;//输出0
字符串长度
使用length()
或size()
,和strlen()不同,size()的时间复杂度是O(1)的
string txt = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
cout << "The length of the txt string is: " << txt.length();
cout << "The length of the txt string is: " << txt.size();
注意size是无符号整数,因此
s.size() <= -1
一定成立
字符串输入输出
string不可以用scanf读
#include <iostream>
#include <cstring>using namespace std;int main()
{string s;cin >> s; // string不可以用scanf读printf("%s\n", s.c_str()); // 返回字符串所存的字符数组的首地址puts(s.c_str());return 0;
}
读入一行
string s1;getline(cin, s1);cout << s1 << endl;
string的比较:
支持 >, <, >=, <=, ==, !=
等所有比较操作,按字典序进行比较。
为string对象赋值:
string s1(10, 'c'), s2; // s1的内容是 cccccccccc;s2是一个空字符串
s1 = s2; // 赋值:用s2的副本替换s1的副本// 此时s1和s2都是空字符串
两个string对象相加:
psptring s1 = "hello, "", s2 = "world\n";
string s3 = s1 + s2; // s3的内容是 hello, world\n
s1 += s2; // s1 = s1 + s2
字面值和string对象相加:
做加法运算时,字面值和字符都会被转化成string对象,因此直接相加就是将这些字面值串联起来:
string s1 = "hello", s2 = "world"; // 在s1和s2中都没有标点符号
string s3 = s1 + ", " + s2 + '\n';
当把string对象和字符字面值及字符串字面值混在一条语句中使用时,必须确保每个加法运算符的两侧的运算对象至少有一个是string:
string s4 = s1 + ", "; // 正确:把一个string对象和有一个字面值相加
string s5 = "hello" + ", "; // 错误:两个运算对象都不是stringstring s6 = s1 + ", " + "world"; // 正确,每个加法运算都有一个运算符是string
string s7 = "hello" + ", " + s2; // 错误:不能把字面值直接相加,运算是从左到右进行的
遍历数组
可以将string对象当成字符数组来处理:
#include <iostream>
#include <string>using namespace std;int main()
{string s = "hello world";for (int i = 0; i < s.size(); i ++ )cout << s[i] << endl;return 0;
}
或者使用基于范围的for语句:
#include <iostream>
#include <string>using namespace std;int main()
{string s = "hello world";for (char c: s) cout << c << endl;for (char& c: s) c = 'a';//想在改变c的同时改变s[i],在前面加上引用符号&使c等价于s[i]cout << s << endl;return 0;
}
数组
初始化memset
memset
函数是C和C++标准库中的一个函数,用于将一块内存中的每个字节都设置为一个给定的值。它通常用于初始化数组或者内存块。memset
函数的原型定义在 <cstring>
(在C++中)或 <string.h>
(在C中)头文件中。
#include <iostream>
#include <cstring>
using namespace std;
int main()
{int a[10];// memset(a, 0, 40);memset(a, 0, sizeof a); // sizeof a 返回a所占用的字节数量return 0;
}
将数组中的每一个字节设置为这个值。
因此,memset一般设置为0或者-1(补码,每一位都是1)
函数原型
在C和C++中,memset
函数的原型如下:
void *memset(void *s, int c, size_t n);
参数
void *s
:指向要填充的内存块的指针。int c
:是一个值,表示要设置的值。尽管这个参数的类型是int
,但实际上只有最低的8位(一个字节)会被用于设置内存块中的值。size_t n
:内存块的大小,即要设置的字节数。
返回值
memset
函数返回一个指向内存块 s
的指针。
使用示例
假设有一个字符数组 arr
,我们想将其所有元素初始化为0:
char arr[100];
memset(arr, 0, sizeof(arr));
这段代码将 arr
数组的所有100个字节都设置为0。
注意事项
memset
适用于简单的数据类型(如字符数组、整数数组等)的初始化,因为它是按字节操作的。对于需要按位初始化的复杂数据类型(如带有构造函数的C++对象),使用memset
可能不会得到预期的效果。- 当使用
memset
设置非零值时,需要注意c
参数只使用了最低的8位,这意味着如果你想用memset
来初始化比一个字节更大的数据类型(如int
、float
等),除非你是将其初始化为0或某个字节值的重复(比如0x01010101
),否则结果可能不是你所期望的。 - 由于
memset
是按字节设置值,对于初始化高级数据结构或需要调用构造函数的对象数组,应使用更适合的方法,如循环或标准库中的std::fill
或std::fill_n
函数。
数组复制memcpy
memcpy
函数是C和C++标准库中用于复制内存块的函数。它从源内存地址开始复制n
个字节到目标内存地址。这个函数对于执行低级别的二进制数据复制非常有效,尤其是当你需要快速复制大量数据时。memcpy
函数的原型定义在<cstring>
(C++中)或<string.h>
(C中)头文件中。
函数原型
在C和C++中,memcpy
函数的原型如下:
void *memcpy(void *dest, const void *src, size_t n);
参数
void *dest
:指向用于存储复制内容的目标内存块的指针。const void *src
:指向要从中复制数据的源内存块的指针。size_t n
:要复制的字节数。
返回值
memcpy
函数返回一个指向目标内存块dest
的指针。
使用示例
假设你有两个数组,source
和destination
,你想将source
数组的内容复制到destination
数组中:
char source[] = "Hello, World!";
char destination[20];memcpy(destination, source, strlen(source) + 1);
这段代码将source
数组包括结尾的空字符(\0
)一共14个字节的内容复制到destination
数组中。
注意事项
memcpy
函数不处理源和目标内存块重叠的情况。如果内存块重叠,复制的结果是未定义的。对于重叠内存块的复制,应使用memmove
函数。- 使用
memcpy
时必须确保目标内存块足够大,可以容纳要复制的数据,否则可能会导致缓冲区溢出,这是常见的安全漏洞之一。 memcpy
是按字节复制数据,因此它可以用于任何类型的数据复制,包括基本数据类型、结构体、类等,但复制对象时要小心,因为简单的字节复制可能不会正确处理对象内部的深层复制需求,比如指针成员的正确复制。对于包含动态分配内存或复杂资源管理的对象,使用memcpy
可能不适合,应考虑更高级的复制机制。
函数
多维数组形参的写法
// 多维数组中,除了第一维之外,其余维度的大小必须指定
void print(int (*a)[10]) {/* … */}
void print(int a[][10]) {/* … */}
#include <iostream>using namespace std;void print(int a[][10])
{for (int i = 0; i < 10; i ++ ){for (int j = 0; j < 10; j ++ )cout << a[i][j] << ' ';cout << endl;}
}int main()
{int a[10][10];for (int i = 0; i < 10; i ++ )for (int j = 0; j < 10; j ++ )a[i][j] = j;print(a);return 0;
}
类与结构体
类与结构体的定义与使用
类中的变量和函数被统一称为类的成员变量。
private
后面的内容是私有成员变量,在类的外部不能访问;public
后面的内容是公有成员变量,在类的外部可以访问。
#include <iostream>using namespace std;const int N = 1000010;class Person
{private:int age, height;double money;string books[100];public:string name;void say(){cout << "I'm " << name << endl;}int set_age(int a){age = a;}int get_age(){return age;}void add_money(double x){money += x;}
} person_a, person_b, persons[100];int main()
{Person c;c.name = "yxc"; // 正确!访问公有变量c.age = 18; // 错误!访问私有变量c.set_age(18); // 正确!set_age()是共有成员变量c.add_money(100);c.say();cout << c.get_age() << endl;return 0;
}
结构体和类的作用是一样的。不同点在于类默认是private,结构体默认是public。
struct Person
{private:int age, height;double money;string books[100];public:string name;void say(){cout << "I'm " << name << endl;}int set_age(int a){age = a;}int get_age(){return age;}void add_money(double x){money += x;}
} person_a, person_b, persons[100];
构造函数
#include <iostream>using namespace std;struct Person
{int age, height;double money;// 特殊的赋值方式Person(int _age, int _height) : age(_age), height(_height){};Person(int _age, int _height, double _money) // 构造函数{age = _age;height = _height;money = _money;}
};int main()
{// 多种初始化方式Person p1(18, 180, 10000);Person p2 = {18, 180, 10000};return 0;
}
指针和引用
指针指向存放变量的值的地址。因此我们可以通过指针来修改变量的值。
#include <iostream>using namespace std;int main()
{int a = 10;int *p = &a;*p += 5;cout << a << endl;return 0;
}
数组名是一种特殊的指针。指针可以做运算:
#include <iostream>using namespace std;int main()
{int a[5] = {1, 2, 3, 4, 5};for (int i = 0; i < 5; i ++ )cout << *(a + i) << endl;return 0;
}
引用和指针类似,相当于给变量起了个别名。
#include <iostream>using namespace std;int main()
{int a = 10;int &p = a;p += 5;cout << a << endl;return 0;
}
STL
multi是可以有重复元素,没有multi的不能有重复元素
相关文章:

C/C++基础语法
C/C基础语法 文章目录 C/C基础语法头文件经典问题链表链表基础操作 秒数转换闰年斐波那契数列打印n阶菱形曼哈顿距离菱形图案的定义大数计算 输入输出格式化输入输出getline()函数解决cin只读入一个单词的问题fgets读入整行输出字符数组(两种方式puts和printf&#…...

Home Assistant:基于Python的智能家居开源系统详解
Home Assistant:基于Python的智能家居开源系统详解 在数字化和智能化的时代,智能家居系统成为了现代家庭的新宠。它们能够让我们更加方便地控制家中的各种设备,实现自动化和个性化的居住体验。其中,Home Assistant作为一款基于Pyt…...
使用vscode进行简单的多文件编译
安装好必要的插件后(如C/C,code runner等)默认生成task.json即可进行单文件运行 涉及到多文件情况可以修改task.json如下: {"version": "2.0.0","tasks": [{"type": "cppbuild&quo…...

Python实现PPT演示文稿中视频的添加、替换及提取
无论是在教室、会议室还是虚拟会议中,PowerPoint 演示文稿都已成为一种无处不在的工具,用于提供具有影响力的可视化内容。PowerPoint 提供了一系列增强演示的功能,在其中加入视频的功能可以大大提升整体体验。视频可以传达复杂的概念、演示产…...

Mysql学习之MVCC解决读写问题
多版本并发控制 什么是MVCC MVCC (Multiversion Concurrency Control)多版本并发控制。顾名思义,MVCC是通过数据行的多个版本管理来实现数据库的并发控制。这项技术使得在InnoDB的事务隔离级别下执行一致性读操作有了保证。换言之࿰…...
Linux下如何生成coredump文件
引言 在linux下执行程序,当出现coredump时,却发现没有生成core文件,或者生成了core文件却不知道在哪里,下面就讲述如何产出core文件,以及指定core文件的产出格式与路径。 打开core文件的大小限制 ulimit -c unlimit…...

eltable 合计行添加tooltip
eltable 合计行添加tooltip 问题描述: eltable 合计行单元格内容过长会换行,需求要求合计行数据超长显示 … ,鼠标 hover 时显示提示信息。 解决方案:eltable合计行没有对外的修改接口,想法是 自己实现一个tooltip&a…...
Secure Boot(安全启动)
Secure Boot(安全启动)的原理基于链式验证,这是一种确保计算机在启动过程中只加载和执行经过认证的软件的机制。这个过程涉及到硬件、固件和操作系统的多个层面。以下是Secure Boot的基本原理: 密钥和证书:Secure Boot…...
大厂面试经验:如何对加密后的数据进行模糊查询操作
加密后的数据对模糊查询不是很友好,本篇就针对加密数据模糊查询这个问题来展开讲一讲实现的思路。 为了数据安全我们在开发过程中经常会对重要的数据进行加密存储,常见的有:密码、手机号、电话号码、详细地址、银行卡号、信用卡验证码等信息…...

修改docker默认存储位置【高版本的docker】
一、修改docker默认存储位置 1、停服务 systemctl stop docker 2、修改/etc/docker/daemon.json添加新的dcoker路径 如"data-root": "/mnt/hdd1/docker" 3、保存后重启服务:systemctl restart docker 二、其他服务的命令 systemctl disab…...

CleanMyMac X2024免费Mac电脑清理和优化工具
CleanMyMac X是一款专业的 Mac 清理和优化工具,它具备一系列强大的功能,可以帮助用户轻松管理和维护他们的 Mac 电脑。以下是一些关于 CleanMyMac X 的主要功能和特点: 智能清理:CleanMyMac X 能够智能识别并清理 Mac 上的无用文件…...

吴恩达机器学习全课程笔记第四篇
目录 前言 P61-P68 激活函数 Softmax算法 P69-P73 Adam算法 更多类型的层 模型评估 P74-P79 偏差和方差 建立表现基准 学习曲线 偏差和方差与神经网络 前言 这是吴恩达机器学习笔记的第四篇,第三篇笔记请见: 吴恩达机器学习全课程笔记第…...
大数据分析师常用函数
常用函数 当进行大数据分析时,SQL中的函数非常丰富,以下是更详细的展开: 窗口函数 (Window Functions): ROW_NUMBER(): 为结果集中的每一行分配一个唯一的整数,用于排序。RANK(): 为结果集中的每一行分配一个排名,相同值会有相同的排名,但会跳过相同排名数量。DENSE_RAN…...

MySQL 主从读写分离入门——基本原理以及ProxySQL的简单使用
一、读写分离工作原理 读写分离的工作原理:在大型网站业务中,当单台数据库无法满足并发需求时,通过主从同步方式同步数据。设置一台主服务器负责增、删、改,多台从服务器负责查询,从服务器从主服务器同步数据以保持一…...

ROS2从入门到精通:理论与实战
ROS是什么? 随着人工智能技术的飞速发展与进步,机器人的智能化已经成为现代机器人发展的终极目标。机器人发展的速度在不断提升,应用范围也在不断拓展,例如自动驾驶、移动机器人、操作机器人、信息机器人等。机器人系统是很多复杂…...
docker 安装minio 一脚shell脚本
要创建一个用于安装Minio的Docker的Shell脚本,你可以按照以下步骤进行。这个脚本会执行以下操作: 拉取Minio的Docker镜像。创建一个Docker容器并映射端口。设置Minio的访问密钥和秘密密钥。持久化存储数据到本地目录。 以下是一个简单的Shell脚本示例&…...
【数据库】mybatis使用总结
文章目录 1. 批量插入、检索<foreach>2. <if> 判断等于情况3. 模糊查询(pgsql为例)4. 分页5. <resultMap > 中collection 和association 6. no conflict do update 1. 批量插入、检索<foreach> <insert id"insertSystemService" >in…...

VR元宇宙的概念|VR体验店加盟|虚拟现实设备销售
VR元宇宙是一个结合了虚拟现实(Virtual Reality)和增强现实(Augmented Reality)等技术的概念,代表着一个虚拟的多维度世界。它是一个由数字化的空间构成的虚拟环境,可以通过虚拟现实设备进行交互和探索。 元…...

MySQL进阶:全局锁、表级锁、行级锁总结
👨🎓作者简介:一位大四、研0学生,正在努力准备大四暑假的实习 🌌上期文章:MySQL进阶:MySQL事务、并发事务问题及隔离级别 📚订阅专栏:MySQL进阶 希望文章对你们有所帮助…...

Python用函数实现代码复用
归纳编程学习的感悟, 记录奋斗路上的点滴, 希望能帮到一样刻苦的你! 如有不足欢迎指正! 共同学习交流! 🌎欢迎各位→点赞 👍 收藏⭐ 留言📝 生命对某些人来说是美丽的,…...

JavaSec-RCE
简介 RCE(Remote Code Execution),可以分为:命令注入(Command Injection)、代码注入(Code Injection) 代码注入 1.漏洞场景:Groovy代码注入 Groovy是一种基于JVM的动态语言,语法简洁,支持闭包、动态类型和Java互操作性,…...

Debian系统简介
目录 Debian系统介绍 Debian版本介绍 Debian软件源介绍 软件包管理工具dpkg dpkg核心指令详解 安装软件包 卸载软件包 查询软件包状态 验证软件包完整性 手动处理依赖关系 dpkg vs apt Debian系统介绍 Debian 和 Ubuntu 都是基于 Debian内核 的 Linux 发行版ÿ…...

Java-41 深入浅出 Spring - 声明式事务的支持 事务配置 XML模式 XML+注解模式
点一下关注吧!!!非常感谢!!持续更新!!! 🚀 AI篇持续更新中!(长期更新) 目前2025年06月05日更新到: AI炼丹日志-28 - Aud…...
rnn判断string中第一次出现a的下标
# coding:utf8 import torch import torch.nn as nn import numpy as np import random import json""" 基于pytorch的网络编写 实现一个RNN网络完成多分类任务 判断字符 a 第一次出现在字符串中的位置 """class TorchModel(nn.Module):def __in…...
智能AI电话机器人系统的识别能力现状与发展水平
一、引言 随着人工智能技术的飞速发展,AI电话机器人系统已经从简单的自动应答工具演变为具备复杂交互能力的智能助手。这类系统结合了语音识别、自然语言处理、情感计算和机器学习等多项前沿技术,在客户服务、营销推广、信息查询等领域发挥着越来越重要…...

AirSim/Cosys-AirSim 游戏开发(四)外部固定位置监控相机
这个博客介绍了如何通过 settings.json 文件添加一个无人机外的 固定位置监控相机,因为在使用过程中发现 Airsim 对外部监控相机的描述模糊,而 Cosys-Airsim 在官方文档中没有提供外部监控相机设置,最后在源码示例中找到了,所以感…...

[ACTF2020 新生赛]Include 1(php://filter伪协议)
题目 做法 启动靶机,点进去 点进去 查看URL,有 ?fileflag.php说明存在文件包含,原理是php://filter 协议 当它与包含函数结合时,php://filter流会被当作php文件执行。 用php://filter加编码,能让PHP把文件内容…...
ubuntu22.04 安装docker 和docker-compose
首先你要确保没有docker环境或者使用命令删掉docker sudo apt-get remove docker docker-engine docker.io containerd runc安装docker 更新软件环境 sudo apt update sudo apt upgrade下载docker依赖和GPG 密钥 # 依赖 apt-get install ca-certificates curl gnupg lsb-rel…...

Xcode 16 集成 cocoapods 报错
基于 Xcode 16 新建工程项目,集成 cocoapods 执行 pod init 报错 ### Error RuntimeError - PBXGroup attempted to initialize an object with unknown ISA PBXFileSystemSynchronizedRootGroup from attributes: {"isa">"PBXFileSystemSynchro…...

表单设计器拖拽对象时添加属性
背景:因为项目需要。自写设计器。遇到的坑在此记录 使用的拖拽组件时vuedraggable。下面放上局部示例截图。 坑1。draggable标签在拖拽时可以获取到被拖拽的对象属性定义 要使用 :clone, 而不是clone。我想应该是因为draggable标签比较特。另外在使用**:clone时要将…...