一:C++中一维数组的加减乘除
在 C++ 中,一维数组的加减乘除操作需要逐个遍历数组元素并对其进行相应的操作:
(1)加法示例:
void addArray(int arr[], int size, int value) {
for (int i = 0; i < size; i++) {
arr[i] += value;
}
}
(2)减法示例:
void subtractArray(int arr[], int size, int value) {
for (int i = 0; i < size; i++) {
arr[i] -= value;
}
}
(3)乘法示例:
void multiplyArray(int arr[], int size, int value) {
for (int i = 0; i < size; i++) {
arr[i] *= value;
}
}
(4)除法示例:
void divideArray(int arr[], int size, int value) {
for (int i = 0; i < size; i++) {
arr[i] /= value;
}
}
在上面的示例中,arr 是一个整型数组,size 是数组的大小,value 是与数组元素进行操作的值。遍历数组的循环使用索引 i,并对每个数组元素进行相应的操作。
两个一维数组的加减乘除
在C++中,对两个一维数组进行加减乘除操作需要对相应的数组元素进行逐个操作,并将结果存储到另一个数组中。
加法示例:
void addArrays(int arr1[], int arr2[], int result[], int size) {
for (int i = 0; i < size; i++) {
result[i] = arr1[i] + arr2[i];
}
}
减法示例:
void subtractArrays(int arr1[], int arr2[], int result[], int size) {
for (int i = 0; i < size; i++) {
result[i] = arr1[i] - arr2[i];
}
}
乘法示例:
void multiplyArrays(int arr1[], int arr2[], int result[], int size) {
for (int i = 0; i < size; i++) {
result[i] = arr1[i] * arr2[i];
}
}
除法示例:
void divideArrays(int arr1[], int arr2[], int result[], int size) {
for (int i = 0; i < size; i++) {
if (arr2[i] != 0) {
result[i] = arr1[i] / arr2[i];
} else {
// Handle division by zero error
// For example, assign a default value to the result[i]
}
}
}
在上面的示例中,arr1 和 arr2 是两个整型数组,result 是存储结果的数组,size 表示数组的大小。通过遍历的方式,对应位置的数组元素进行相应的操作,结果存储到 result 数组中。
二:C++中二维数组
1:二维数组初始化
(1)第一种初始化方法(以元素类型为int为例)
初始化为1:
vector<vector<int>> vec(row, vector<int> (col,1));
(2)第二种初始化方法(使用 resize() 函数)
int row = 9;
int col = 9;
//vector<vector<int>> vec(row, vector<int> (col,1));
vec.resize(row);
for(int i = 0; i < vec.size(); i++) {
vec[i].resize(col);
}
for(int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
vec[i][j] = 2;
}
}
//Qt中
int row = 9;
int col = 9;
//vector<vector<int>> vec(row, vector<int> (col,1));
std::vector<std::vector<int>> vec;
//使用 std::vector 的向量的向量,std::vector<std::vector<int>>。
//创建一个 std::vector 的向量,其中每个元素都是一个 std::vector<int> 类型的向量,来表示二维数
//组。每个内层的 std::vector<int> 向量表示一行数据,而外层的 std::vector 向量表示所有的行。
vec.resize(row);
for(int i = 0; i < vec.size(); i++) {
vec[i].resize(col);
}
for(int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
vec[i][j] = 2;
qDebug() << vec[i][j];
} qDebug() << endl;
}
//其他写法
int m = 2;
int n = 3;
vector<vector<int>> vec1(m, vector<int>(n)); // 初始化方法1, 默认初始化为0
vector<vector<int>> vec2 = vector<vector<int>>(m, vector<int>(n)); // 初始化方法2,默认初始化为0
vector<vector<int>> vec3 = vector<vector<int>>(m, vector<int>(n)) = {{1,2,3}, {4,5,6}};
(3)第三种初始化方法(动态分配的方式,这种写法比较灵活,在定义的时候不需要指明二维矩阵的行数和列数)
/* 使用动态分配内存的形式,用malloc
*/
int **array // array[M][N]
array = (int **)malloc(M * sizeof(int *));
for(int i = 0; i < M; i++) {
array[i] = (int *)malloc(N * sizeof(int));
}
// 释放
for(int i = 0; i < M; i++)
free(array[i]);
free(array);
2:二维数组元素插入 push_back
int row = 3;
int col = 3;
// std::vector<int> temp; // 创建辅助向量
// 将 int 值封装到辅助向量中
// int value = 4;
// temp.push_back(value);
//vector<vector<int>> vec(row, vector<int> (col,1));
std::vector<std::vector<int>> vec;//二维数组初始化
vec.resize(row);
for(int i = 0; i < vec.size(); i++)
{
vec[i].resize(col);
}
for(int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
vec[i][j] = 2;
qDebug() << vec[i][j];
}
qDebug() << endl;
}
vec[0].push_back(4); // 在特定行插入元素
vec[1].push_back(4);
vec[2].push_back(4);
vec.push_back(std::vector<int>{1, 2, 3,4}); // 在二维向量末尾插入一行
// 输出二维向量元素
for (const auto& row : vec) {
for (int num : row) {
std::cout << num << " ";
}
std::cout << std::endl;
};
3:二维数组存储方式
在 C++ 中,二维数组可以以两种方式存储:
1.连续存储方式(行主序):在内存中以连续的方式存储二维数组的元素。这种方式被称为行主序,因为每一行的元素在内存中是连续存储的,而不同行之间的元素则可能不是连续的。这种存储方式的优势是可以方便地进行指针运算和访问连续的元素。
(1) 计算机会给二维数组分配一块连续的存储空间
(2) 数组名表示该二维数组的首地址,从首地址开始,依次存入第一行、第二行….
(3) 每一行的存储方式,从首地址开始,依次存入第一个元素、第二个元素…..
(4) 每个字节占用相同的字节数【字节取决于数组类型】
(5) 数组中的每个元素之间的地址是连续的。
2.非连续存储方式:使用嵌套的动态数据结构,例如使用 std::vector 的向量的向量(std::vector<std::vector<int>>)或动态分配的指针的指针(int** array)来表示二维数组。在这种方式下,每一行可以具有不同的长度,元素在内存中的存储位置可以是不连续的。
对于连续存储方式,二维数组的各个元素在内存中是依次存储的,根据二维数组的行数和列数,可以通过简单的指针运算来计算元素的地址。
对于非连续存储方式,由于每一行的长度可能不同,因此不能通过简单的指针运算来确定元素的地址。而是需要通过多级的索引或指针来访问二维数组的元素。
连续存储方式适合于具有固定大小的矩阵,可以提供快速、连续的访问。非连续存储方式则更加灵活,适合于行数和列数不确定或需要动态改变的情况。
4:二维数组常见操作函数
#include <iostream>
#include <vector>
int main() {
// 创建一个初始大小为 3x3 的二维数组
std::vector<std::vector<int>> array(3, std::vector<int>(3, 0));
// 添加一行
array.push_back(std::vector<int>{4, 5, 6});
// 在指定位置插入一列 插入的是第 i 行的索引为 2 的位置之前,也就是在每一行的第三个元素之前插
//\入一个值为 2 的元素。
for (int i = 0; i < array.size(); ++i) {
array[i].insert(array[i].begin() + 2, 2);
}
// 删除最后一行
array.pop_back();
// 删除指定位置的元素
array[1].erase(array[1].begin() + 1);
// 修改指定位置的元素的值
array[0][0] = 1;
// 调整行数和列数
array.resize(2);
for (int i = 0; i < array.size(); ++i) {
array[i].resize(2);
}
// 输出二维数组的值
for (int i = 0; i < array.size(); ++i) {
for (int j = 0; j < array[i].size(); ++j) {
std::cout << array[i][j] << ' ';
}
std::cout << std::endl;
}
return 0;
}
5:二维数组的引用
方法1:使用指针引用:
int rows = 3;
int cols = 3;
int array1[rows][cols] = {
{0, 1, 2},
{3, 4, 5},
{6, 7, 8}
};
//array_ptr 是指向数组的指针,使用指针算术运算来访问和修改二维数组的元素。而 array_ref 是对整个二维数组的引用,可以直接使用所提供的引用来访问和修改二维数组的元素。
// int (*array_ptr)[cols] = array; 是将 array 绑定到一个指向大小为 cols 的数组的指针上。这个指针可以用来遍历二维数组和访问元素。通过指针,可以使用指针算术运算来遍历二维数组。
// int (&array_ref)[rows][cols] = array; 是将 array 直接绑定到一个大小为 rows 行 cols 列的完整二维数组引用上。这个引用提供了对整个二维数组的直接访问和修改能力。
// 创建指向数组的指针引用
int (&array1_ref)[rows][cols] = array1;
// 使用引用访问和修改元素
int element_ref = array1_ref[2][2];
array1_ref[2][2] =9;
// 声明二维数组的指针引用
int (*array_ptr)[cols] = array1;
// 通过指针引用来操作二维数组的元素
int element = array_ptr[1][1];
array_ptr[1][1] = 3;
for (int i = 0; i < 3; ++i) {
for (int j = 0; j < 3; ++j) {
std::cout << array2[i][j] << ' ';
}
std::cout << std::endl;
}
方法2:使用向量引用:
std::vector<std::vector<int>> array2 = {
{0, 1, 2},
{3, 4, 5},
{6, 7, 8}
};
// 声明二维向量的引用
std::vector<std::vector<int>>& array2_ref = array2;
// 通过引用来操作二维向量的元素
int element1 = array2_ref[1][1];
array2_ref[1][1] = 0;
for (int i = 0; i < 3; ++i) {
for (int j = 0; j < 3; ++j) {
std::cout << array2[i][j] << ' ';
}
std::cout << std::endl;
}