前言

数组之前的知识是基础中的基础就不再整理了,只挑几个稍微要看一下的。

switch语句

基本语法例子示范

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include<iostream>
using namespace std;
int main() {
int day = 3;
switch (day) {
case 1:
std::cout << "Monday" << std::endl;
break;
case 2:
std::cout << "Tuesday" << std::endl;
break;
case 3:
std::cout << "Wednesday" << std::endl;
break;
case 4:
std::cout << "Thursday" << std::endl;
break;
case 5:
std::cout << "Friday" << std::endl;
break;
default:
std::cout << "Weekend" << std::endl;
}
return 0;
}

输出结果为 Wednesday;

如果case语句中没有break;那么将执行该case下的所有语句:

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

int main() {
int day = 3;
switch (day) {
case 1:
std::cout << "Monday" << std::endl;
// 没有break,继续执行下一个case
case 2:
std::cout << "Tuesday" << std::endl;
// 没有break,继续执行下一个case
case 3:
std::cout << "Wednesday" << std::endl;
// 没有break,继续执行下一个case
case 4:
std::cout << "Thursday" << std::endl;
// 没有break,继续执行下一个case
case 5:
std::cout << "Friday" << std::endl;
// 没有break,继续执行下一个case
default:
std::cout << "Weekend" << std::endl;
}
return 0;
}

输出结果:

1
2
3
4
Wednesday
Thursday
Friday
Weekend

其他需要注意的点:

  • switch后圆括号中的表达式的类型只能是整型或能够隐式转换为整型的类型(如字符型,或枚举型)

  • 每个case语句后必须是与表达式类型兼容的一个常量(但不能是字符串常量)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
int main() {
char grade = 'B';
switch (grade) {
case 'A': // 字符常量,与表达式类型兼容
// 代码块
break;
case 2: // 整数常量,与表达式类型兼容
// 代码块
break;
case 2.5: // 错误,浮点数常量与字符类型不兼容
// 代码块
break;
case "B": // 错误,字符串常量不兼容
// 代码块
break;
}

return 0;
}

do-while语句

基本语法例子

1
2
3
4
5
6
7
8
9
10
11
12
#include <iostream>

int main() {
int count = 0;

do {
std::cout << "Count: " << count << std::endl;
count++;
} while (count < 5);

return 0;
}
  • 注意while后面有分号;

字符串数组常用函数

strcat-字符串连接函数

函数原形:

1
char* strcat(char str1[],const char str2[]);

作用

把str2中的字符串连接到str1字符的后面, str1中字符的结束标志\0被st2里的字符串及其结束标志所覆盖。本函数返回值是str1的首地址。

image-20231220200644095

strcpy-字符串复制函数

函数原型

1
char* strcat(char str1[],const char str2[]);

作用

把str2中的字符串复制到str1中,str2中的串结束标志”\0”也一同复制。参数str2还可以是一个字符串常量,这时相当于把一个字符串赋予一个字符数组。

image-20231220200904869

strcmp-字符串比较函数

函数原型

1
int strcmp(const char str1[],const char str2[]);

作用

依照ASCII码表中的值的大小,依次比较两个字符串中对应位置上的字符,并由函数返回值返回比较结果。

image-20231220201312707

strlen-计算字符串长度函数

函数原型

1
int strlen(const char str[]);

作用

计算字符串中的长度,返回首次出现的结束标志\0之前的字符数,并作为返回值。

计算时不包括\0

指针

指针的定义与声明

1
2
3
int *ptr;  // 定义一个指向整数的指针
double *dblPtr; // 定义一个指向双精度浮点数的指针
char *charPtr; // 定义一个指向字符的指针

取地址操作符&

取地址操作符 & 用于获取变量的内存地址:

1
2
int number = 42;
int *ptr = &number; // 将变量number的地址赋给指针ptr

指针和函数:

指针可以用于传递地址,从而在函数中修改实际参数的值:

1
2
3
4
5
6
7
8
9
10
11
void modifyValue(int *ptr) {
*ptr = 100;
}

int main() {
int number = 42;
int *ptr = &number;

modifyValue(ptr); // 传递指向number的指针给函数
// 现在,number的值被修改为100
}

指针解引用操作符 *

指针解引用操作符 * 用于访问指针所指向地址的值:

1
int value = *ptr;  // 获取ptr指针所指向地址的值,将其赋给变量value

动态内存分配与释放:

使用 new 操作符可以在运行时动态分配内存,而 delete 操作符用于释放动态分配的内存:

1
2
3
int *dynamicPtr = new int;  // 动态分配一个整数大小的内存空间
// 使用 dynamicPtr 操作内存
delete dynamicPtr; // 释放动态分配的内存

指针和数组

指针和数组之间有着密切的关系,指针可以用于访问数组元素:

1
2
int numbers[5] = {1, 2, 3, 4, 5};
int *arrPtr = numbers; // 将数组名赋给指针,指向数组的第一个元素

空指针

空指针表示不指向任何有效的内存地址。在C++中,可以使用 nullptr 来表示空指针:

1
int *nullPtr = nullptr;  // 定义一个空指针

常量指针和指针常量

  • 常量指针:指针本身不可变,但指向的值可变。

    1
    2
    int value = 42;
    const int *ptr = &value; // 指向常量的指针
  • 指针常量:指向的值不可变,但指针本身可变。

    1
    2
    int value = 42;
    int *const ptr = &value; // 常量指针

链表

链表的创建

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
int main(){
Set a, b;
init(&a);
init(&b);
createSet(&a);
createSet(&b);
return 0;
}

int main(){
int n, k, m;
cin >> n >> k >> m;
List lst;
createList(lst, n);
return 0;
}

向前插入生成

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
struct Node
{
int data;
Node* next;
};

struct Set
{
int num;
Node* head;
};

void init(Set* x)
{
x->head = NULL;
x->num = 0;
}

void createSet(Set* x)
{
//生成链表时一定采用往前插入的方法,即每个新产生的结点插入到链表的第一个结点的前面。
int n, i;
cin >> n;
Node* node = new Node;
cin >> node->data;
node->next = NULL;
x->head = node;
for (i = 0; i < n-1; i++) {
Node* node = new Node;
cin >> node -> data;
node -> next = x->head;
x->head = node;
}

}

向后插入

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
struct Node {
int data;
Node* next;
};

struct List {

Node* head;
int length;
};

void createList(List& lst, int n) {
//生成链表时采用往后插入的方法,即每个新结点插入到链表尾部。
lst.length = n;
Node* _head = new Node;
_head->data = 1;
lst.head = _head;
Node* tail = _head;
int i = 2;
for (i; i <= n; i++) {
Node* node = new Node;
node->data = i;
tail->next = node;
tail = tail->next;
}
}

实验题目

漂亮的递归

【问题描述】键盘输入正整数 n,求出n与其反序数x之和并输出。例如,输入2038,n+x = 2038 +8302 =10340,输出应为10340。要求:编写函数实现数据转换成反序数值。【输入形式】输入一个整数; 【输出形式】输出一个整数; 【样例输入】2038 【样例输出】10340 【样例说明】不要任何输入输出的文字提示。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream>
int reverse(int n, int store = 0){
if (n < 10) return store + n;
else {
store += n % 10;
return reverse(n / 10, store * 10);
}
}

int main(){
int n, reverse_num;
std::cin >> n;
reverse_num = reverse(n);
std::cout << n + reverse_num;
return 0;
}

写递归最关键的地方在于基本条件,基本条件出来了,递归的转折点也就出来了。

数组

数组的旋转

【问题描述】 旋转是图像处理的基本操作,在这个问题中,你需要将一个图像逆时针旋转90度。 计算机中的图像表示可以用一个矩阵来表示,为了旋转一个图像,只需要将对应的矩阵旋转即可。 【输入格式】 输入的第一行包含两个整数n, m(1≤n, m≤10),分别表示图像矩阵的行数和列数。 接下来n行每行包含m个整数,表示输入的图像。

【输出格式】 输出m行,每行包含n个整数,表示原始矩阵逆时针旋转90度后的矩阵。每行后空格结束。

1
2
3
4
5
6
7
8
【样例输入】
2 3
1 5 3
3 2 4
【样例输出】
3 4
5 2
1 3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <iostream>
using namespace std;
int main() {
int n, m;
cin >> n >> m;
int ls[10][10] = { 0 };
int ls2[10][10] = { 0 };
//初始化ls数组
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
cin >> ls[i][j];
}
}
//数组旋转
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
ls2[i][j] = ls[j][m - i - 1];
}
}
//输出旋转后的数组
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
cout << ls2[i][j]<<" ";
}
cout << endl;
}
}

也可以动态开辟:

// 使用new运算符分配内存
int** ls = new int* [n];
for (int i = 0; i < n; ++i) {
ls[i] = new int[m];
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
cin >> ls[i][j];
}
}

求二维数组的鞍点

【问题描述】找出一个二维数组(以三行四列的数组为例)中的鞍点,即该位置上的元素在该行上值最大,在该列上值最小(也可能没有鞍点)。

【输入形式】二维数组(以三行四列的数组为例)

【输出形式】如果有鞍点,输出鞍点的值及所在行列(例如[1][2]=96 is Saddle Point),如果没有,输出没有鞍点(例如 No Saddle Point)

1
2
3
4
5
6
【样例输入】 
9 80 205 40
90 60 96 1
210 3 101 89
【样例输出】
[1][2]=96 is Saddle Point
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include <iostream>
using namespace std;

int main() {
int ls[3][4] = { 0 };
int min = 999, max = 0;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 4; j++) {
cin >> ls[i][j];
}
}
int row = 0, col = 0;
for(int i = 0;i<3;i++){
for (int j = 0; j < 4; j++){
if (ls[i][j] > max) {
max = ls[i][j];
col = j;
}
}
for (int j = 0; j < 3; j++) {
if (ls[j][col] < min) {
min = ls[j][col];
row = j;
}
}
if (ls[row][col] == max) {
break;
}
else {
max = 0;
min = 999;
}
}
if (min == max) cout << "[" << row << ']' << '[' << col << "] = " << min << " is Saddle Point";
else cout << 'NO';
}

字符串数组

【题目描述】
输入一个字符串(长度不超过255),请找出字符串中的所有的正整数(如-12,当作12),然后输出其中的素数。如果出现12.5,则看作12和5两个整数。

1
2
3
4
【样例输入】
How3.5many12prime-17number79inthestring.
【样例输出】
3 5 17 79
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iostream>
using namespace std;

bool is_prime(int n) {
for (int i = 2; i < n; i++) {
if (n % i == 0) return false;
}
return true;
}

int main() {
string str;
cin >> str;
int i = 0;
while (i < str.length()) {
int num = 0;
while (str[i] > '0' && str[i] <= '9') {
num = num * 10 + str[i] - '0';
i++;
}
if (is_prime(num) && num > 1) cout << num << " ";
i++;
}
}