20250301-Rain
1. 多维数组
一种原地转置的方法,注意不要重复转置,这样输出的会是原始的矩阵。
/*
1. 矩阵转置
输入一个数字构成的矩形, 将矩形的值进行转置后打印
输入:
第一行 正整数n(1<n<10), 表示矩阵的边长
随后输入一个矩阵
输出:
转置后的矩阵
样例输入:
3
1 2 3
4 5 6
7 8 9
样例输出:
1 4 7
2 5 8
3 6 9
*/
#include <iostream>
#include <vector>
using namespace std;
int main(void)
{
int n;
cout << "Please input 'n': ";
cin >> n;
vector<vector<int>> m_matrix(n, vector<int>(n, 0));
cout << "Please input the elements of matrix: " << endl;
for(auto &p : m_matrix)
{
for(auto &q : p)
{
cin >> q;
}
}
// 互相交换行与列。
for(int i = 0; i < n; i++)
{
// 注意内循环的循环条件,已经换过的行和列要跳过
for(int j = i; j < n; j++)
{
// 对角元素不用交换
if(i != j)
{
int temp = m_matrix[i][j];
m_matrix[i][j] = m_matrix[j][i];
m_matrix[j][i] = temp;
}
}
}
// print
for(auto &p : m_matrix)
{
for(auto q : p)
{
cout << q << " ";
}
cout << endl;
}
return 0;
}
2. 字符串
核心逻辑是遇到 分隔符(空格 或者 逗号 或者 句号等等) 要进行数据的检查更新。
可以利用 GDB 等工具进行断点调试,观察程式的演算过程。
/*
4. 背单词
张三最近在背单词, 他为了挑战自我, 打算到英文文档中复制一段, 然后抽出自己不认识的单词.
张三发现, 长单词几乎都是自己不认识的. 于是他打算从最长的开始背.
现在需要你帮忙设计一个程序, 输入一段英文句子, 从中找到最长的那个单词.
输入: 字符串S, S只包含英文字符和空格, 输入以.表示结束.
输出: 两个整数, 分别表示这个单词的位置(起始下标)和单词的长度.
(如果最长的单词有多个, 输出第一个)
(S长度<100)
样例输入1:
Please enter your mobile number.
样例输出1:
0 6
样例输入2:
Please enter the verification code.
样例输出2:
17 12
*/
#include <iostream>
#include <string>
using namespace std;
int main(void)
{
string S;
cout << "Please input 'S': ";
getline(cin, S); // 注意如果使用一般的 cin 遇到空格就停止了,只能输入不带空格的字符串
int max_start = 0;
int max_len = 0;
int start = 0;
int len = 0;
for(int p = 0; p < S.length(); p++)
{
// 如果不是字母,重置计数,记录下一个位置的下标,并且跳过本次循环
if(!isalpha(S[p]))
{
len = 0;
start = p + 1;
continue;
}
// 当长度超过最大值才更新。这样可以保证有多个 max 时,只输出第一个。
len++;
if(max_len < len)
{
max_start = start;
max_len = len;
}
}
cout << max_start << ' ' << max_len << endl;
return 0;
}
3. 指针
直接运行程序,会发现终端有输出:
problem.cpp: In function 'int* fun()':
problem.cpp:11:12: warning: address of local variable 'a' returned [-Wreturn-local-addr]
11 | return a;
| ^
problem.cpp:10:9: note: declared here
10 | int a[] = {3, 4, 5, 6};
| ^
没有报错,但是程序也没有预期输出,必然是有问题的。
警告信息:warning: address of local variable 'a' returned [-Wreturn-local-addr]
翻译一下就是,返回的其实是函数内部创建局部变量的地址。
这里其实不是很明白,可以选择复制信息到 Google。
参考 博客
这里解释的很到位了,其实局部变量在退出函数的时候,分配的内存也就找不到了......意味着您无法再使用该指针,因为它不再指向变量占用的内存。使用它会导致未定义的行为。
问题有两种解决方案:
第一种是使用 动态分配数组
new[]
,并返回该指针。使用 分配的内存new[]
永远不会超出范围,直到您使用delete[]
它。第二种解决方案是在调用函数中定义数组,并将指针作为参数传递给它,并让函数填充它。
由于这是一个 C++ 问题,因此更推荐第三种解决方案:使用
std::array
。然后您可以在函数内部本地声明数组,并返回对象,并且对象和编译器将确保根据需要复制数据。
另外,注意到 int *c = (int *)malloc(16); // include <stdlib.h>
代码也有问题,使用了动态内存分配函数 malloc 后没有及时进行 free,虽然程序没有提示,但是会造成内存泄漏或更严重的后果...这里也补上
代码
这里提供两种方案的代码。
方案一
手动分配 动态内存 并 返回动态内存,这样不会由于函数的结束 而程序出错。
使用 new 和 delete 手动管理内存
#include <stdio.h>
#include <stdlib.h>
int *fun()
{
int *a = new int[4]{3, 4, 5, 6};
return a;
}
int main()
{
int *b = fun();
int *c = (int *)malloc(16); // include <stdlib.h>
printf("%d", b[0]);
delete b;
free(c);
}
请记住,如果您执行上述操作,则必须确保delete []
在调用函数中调用返回的指针。
方案三(C++)
为了避免手动分配和释放内存的麻烦,可以使用std::vector<int>
作为返回类型。
另外,由于数组的大小固定为 4,因此使用std::array<int, 4>
比使用 更好std::vector<int>
:
#include <stdio.h>
#include <stdlib.h>
#include <array>
std::array<int, 4> fun()
{
std::array<int, 4> a = {3, 4, 5, 6};
return a;
}
int main()
{
std::array<int, 4> b = fun();
int *c = (int *)malloc(16); // include <stdlib.h>
printf("%d", b[0]);
free(c);
}
这样,内存管理就会自动为您完成。
Last updated