2024/08/13

我在此处先挖个坑,以后在补(不是 _(:з」∠)_

C++语法基础

标准开局

1
2
3
4
5
6
7
#include <cstdio>
#include <iostream>

int main() {
// do something...
return 0;
}

scanf&printf

1
2
3
4
5
6
7
8
9
#include <cstdio>

int main() {
int x, y;
scanf("%d%d", &x, &y); // 读入 x 和 y
printf("%d\n%d", y, x); // 输出 y,换行,再输出 x
return 0;
//注:printf中不能使用std::string的变量类型
}
1
2
const char* string_variable = "Hatsune_Miku";
printf(string_variable); //等效于py中的str 可替代std::string

upd 2024/08/19 应用 char[] 数组的方式实现字符串

获取大小

sizeof() 获取变量占用的字节数

strlen()string length, 获取字符在\0之前的字符数量

1.%s 表示字符串。
2.%c 表示字符。
3.%lf 表示双精度浮点数 (double)。
4.%lld 表示长整型 (long long)。根据系统不同,也可能是%I64d。
5.%u 表示无符号整型 (unsigned int)。
6.%llu 表示无符号长整型 (unsigned long long),也可能是%I64u。

About other
%.6lf, 用于控制输出浮点数位数


流程控制语句

判断

if-else 语句

以下是 if-else 语句的基本结构

1
2
3
4
5
6
7
8
9
if (条件1){
主体1;
} else if(条件2){
主体2;
} else if (条件3){
主体3;
} else{
主体4;
}

switch-case-default 语句

1
2
3
4
5
6
7
8
switch (选择句) {
case 标签1:
主体1;
case 标签2:
主体2;
default:
主体3;
}

switch 语句执行时,先求出选择句的值,然后根据选择句的值选择相应的标签,从标签处开始执行。

特别的 switch 语句中还要根据需求加入 break 语句进行中断,否则在对应的 case 被选择之后接下来的所有 case 里的语句和 default 里的语句都会被运行。

同样的 switch 的 case 分句中也可以选择性的加花括号。不过要注意的是,如果需要在 switch 语句中定义变量,花括号是必须要加的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <cstdio>
#include <iostream>
using namespace std;

int main(){
int a;
cin>>a;
switch(a){
case 1:
cout<<"Hatsune Miku"<<endl;
break;
case 2:
cout<<"Len"<<endl;
break;
case 3:
cout<<"Rin"<<endl;
break;
default:
cout<<"Luo Tianyi"<<endl;
break;
}
return 0;
}

循环

for循环

1
2
3
for (初始化; 判断条件; 更新) {
循环体;
}

执行顺序

1
2
3
4
5
6
7
8
int main(){
std::string name = "Luo Tianyi";
for (int i=0;i<10;i++){ //0-9
cout<<name[i]<<" ";
}
return 0;
}
//out:L u o T i a n y i

while循环

1
2
3
while (判断条件){
循环体;
}

执行顺序

1
2
3
4
5
6
7
8
9
10
11
12
int main(){
int n = 1;
while (n<101){
if (n%2){
cout<<n<<" ";
}
n++;

}
return 0;
}
//1-100的所有奇数

do-while循环

1
2
3
do {
循环体;
} while (判断条件);

执行顺序

break 与 continue 语句

break 语句的作用是退出循环。

continue 语句的作用是跳过循环体的余下部分。


高级数据类型

数组

_数组是存放相同类型对象的容器,数组中存放的对象没有名字,而是要通过其所在的位置访问。数组的大小是固定的,不能随意改变数组的长度。_

数组的声明形如 a[d], a 是数组的名字,d 是数组中元素的个数, d 应该是一个整型的常量表达式。

tips: 应该尽量将较大的数组定义为全局变量。因为局部变量会被创建在栈区中,过大(大于栈的大小)的数组会爆栈,进而导致 RE。如果将数组声明在全局作用域中,就会在静态区中创建数组。

与py类似

结构体

1
2
3
4
5
6
7
//定义一个结构体
struct Student {
//在内部创建你需要的数据类型
char name[10];
int age;
char sex[5];
} stu ;//stu是变量
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
int main(){
/*struct student stu = {"Luo Tianyi",24,"m"};
return 0; 定义后直接初始化*/

/*struct student stu;
strcpy(stu.name,"Hatsune Miku");//char类型要用strcpy()函数
stu.age = 24;
strcpy(stu.sex,"f"); 先声明,再赋值*/

//注:定义好结构体后如果不直接进行初始化,那么在后续的给结构体中内容赋值时不能在一次性全部赋值了。

//struct student stu = {.age=24,.name="Luo Tianyi",.sex="f"}; 未知报错

//当我们想使用结构体中的内容时,我们只需要用 structName.variableName 即可。
cout<<stu.name<<endl;
cout<<stu.age<<endl;
cout<<stu.sex<<endl;

return 0;
}

strcpy(a,b)

strcpy,即string copy(字符串复制)的缩写。

strcpy是C++语言的一个标准函数,strcpy()把含有’\0’结束符的字符串复制到另一个地址空间,返回值的类型为char*。

联合体

查看全部(・ω< )★

_联合体(union)是特殊的类类型,它在一个时刻只能保有其一个非静态数据成员。_

联合体在 2023 年正式被加入 NOI 大纲入门级中。

定义联合体
联合体声明的类说明符与类或 结构体 的声明相似:

1
2
3
4
union MyUnion {
int x;
long long y;
} x;

联合体的定义与结构体类似。按照上述定义,MyUnion 同样可以当作一种自定义类型使用。名称 MyUnion 可以省略。

访问/修改成员元素
与结构体类似,同样可以使用 变量名.成员名 进行访问。

联合体所占用的内存空间大小 不小于 其最大的成员的大小,所有成员 共用内存空间与地址。当一个成员被赋值,由于内存共享,该联合体中的其他成员都会被覆盖。即同一时刻联合体中只能保存一个成员的值。

指针

查看全部(・ω< )★

指针是一个变量,可以存储一个对象的内存地址。

1
2
3
4
5
6
7
8
9
10
11
12
int main(){
int a = 1145;
int b = 1919;

int *pointerA = &a;
int *pointerB = &b;

*pointerB-=*pointerA;
cout<<*pointerA<<endl<<*pointerB<<endl<<a<<endl<<b;
//1145 774 1145 774
return 0;
}

在上述代码中通过 & —— 取地址操作符 来使指针 pointerA,pointerB 取到 a,b 的地址

1
int *pointerA = &a;

这⾥pointerA左边写的是 int* , * 是在说明pointerA是指针变量,⽽前⾯的 int 是在说明 pointerA 指向的是整型(int)类型的对象。

在C++中,我们我们只要拿到了地址(指针),就可以通过地址找到地址指向的对象,这⾥必须学习⼀个操作符叫解引⽤操作符 * 用法如上述代码


函数

函数的声明

1
int function(int,int); 

第一个int: return 返回的值, **特别的** 若函数没有返回值,则函数类型为void类型

括号中的int: 传入的值的类型

函数的定义

1
2
3
int function(int x, int y){
return x+y
}
**特别的** 在同一文件中,可将函数的声明与定义整合在一起
1
2
3
4
5
6
7
8
9
10
11
12
13
void _and_(int a, int b){
a++;
b++;
}

int main(){
int x = 2;
int y = 3;
_and_(x,y);
cout<<x<<" "<<y;
//2 3
return 0;
}

在上面的例子中,在 __and__ 中对变量 a 和 b 的修改,并不会影响到调用处的变量 即变量x的值。

1
2
3
4
void _and_(int &a, int &b){
a++;
b++;
}

上述代码中,我们看到函数参数列表中的「int」后面添加了一个「&(and)」,这表示对于 int 类型的 引用(reference)。

在调用 __and__ 时,在 __and__ 中的 a 和 b,可以理解为调用处 x 和 y 变量的「别名」,即 __and__ 中对 a 和 b 的操作,就是对调用处 x 和 y 的操作。


C++ 标准库

简介

查看简介(・ω< )★

首先需要介绍的是 C++ 本身的版本。由于 C++ 本身只是一门语言,而不同的编译器对 C++ 的实现方法各不一致,因此需要标准化来约束编译器的实现,使得 C++ 代码在不同的编译器下表现一致。C++ 自 1985 年诞生以来,一共由国际标准化组织(ISO)发布了 5 个正式的 C++ 标准,依次为 C++98、C++03、C++11(亦称 C++0x)、C++14(亦称 C++1y)、C++17(亦称 C++1z)、C++20(亦称 C++2a)。C++ 标准草案在 open-std 网站上,最新的标准 C++23(亦称 C++2b)仍在制定中。此外还有一些补充标准,例如 C++ TR1。

每一个版本的 C++ 标准不仅规定了 C++ 的语法、语言特性,还规定了一套 C++ 内置库的实现规范,这个库便是 C++ 标准库。C++ 标准库中包含大量常用代码的实现,如输入输出、基本数据结构、内存管理、多线程支持等。掌握 C++ 标准库是编写更现代的 C++ 代码必要的一步。C++ 标准库的详细文档在 cppreference 网站上,文档对标准库中的类型函数的用法、效率、注意事项等都有介绍,请善用。

需要指出的是,不同的 OJ 平台对 C++ 版本均不相同,例如 最新的 ICPC 比赛规则 支持 C++20 标准。根据 NOI 科学委员会决议,自 2021 年 9 月 1 日起 NOI Linux 2.0 作为 NOI 系列比赛和 CSP-J/S 等活动的标准环境使用。NOI Linux 2.0 中指定的 g++ 9.3.0 默认支持标准 为 C++14,并支持 C++17 标准,可以满足绝大部分竞赛选手的需求。因此在学习 C++ 时要注意比赛支持的标准,避免在赛场上时编译报错。

STL 即标准模板库(Standard Template Library),是 C++ 标准库的一部分,里面包含了一些模板化的通用的数据结构和算法。由于其模板化的特点,它能够兼容自定义的数据类型,避免大量的造轮子工作。NOI 和 ICPC 赛事都支持 STL 库的使用,因此合理利用 STL 可以避免编写无用算法,并且充分利用编译器对模板库优化提高效率。