- C++
C++ 二维数组教程
- 2024-12-24 19:38:46 @
一、二维数组的定义
在C++中,二维数组是一种数据结构,它可以被看作是一个具有行和列的表格。
-
语法格式
- 二维数组的声明语法如下:
数据类型 数组名[行数][列数];
- 例如,要声明一个整型的二维数组,有3行4列,可以这样写:
int myArray[3][4];
- 这里,
int
是数据类型,表示数组中的元素是整型,myArray
是数组名,3
表示行数,4
表示列数。
- 二维数组的声明语法如下:
-
初始化
- 二维数组可以在声明时进行初始化。
- 完全初始化:
int myArray[2][3] = { {1, 2, 3}, {4, 5, 6} };
- 这里第一行的元素是
1
、2
、3
,第二行的元素是4
、5
、6
。
- 这里第一行的元素是
- 部分初始化:
int myArray[2][3] = { {1, 2}, {3} };
- 对于未初始化的元素,C++会自动将其初始化为0。所以在这个例子中,第一行的第三个元素和第二行的后两个元素都将是0。
二、二维数组的访问
- 通过下标访问
- 可以使用两个下标来访问二维数组中的元素,第一个下标表示行,第二个下标表示列。
- 例如,要访问上面
myArray
数组中第二行第三列的元素,可以这样写:int element = myArray[1][2];
- 注意,下标是从0开始计数的,所以第二行对应的下标是
1
,第三列对应的下标是2
。
- 注意,下标是从0开始计数的,所以第二行对应的下标是
- 遍历二维数组
- 使用嵌套的
for
循环可以遍历二维数组。 - 例如:
for (int i = 0; i < 2; i++) { for (int j = 0; j < 3; j++) { std::cout << myArray[i][j] << " "; } std::cout << std::endl; }
- 外层
for
循环控制行,内层for
循环控制列,这样就可以逐个访问数组中的元素并进行操作,如打印出来。
- 外层
- 使用嵌套的
三、二维数组作为函数参数
- 传递二维数组给函数
- 当把二维数组作为函数参数时,函数原型需要指定数组的第二维大小。第一维大小可以省略。
- 例如:
void printArray(int arr[][3], int rows);
- 这里
arr
是二维数组参数,3
是列数,rows
是行数参数。
- 这里
- 函数实现示例
- 函数实现如下:
void printArray(int arr[][3], int rows) { for (int i = 0; i < rows; i++) { for (int j = 0; j < 3; j++) { std::cout << arr[i][j] << " "; } std::cout << std::endl; } }
- 调用这个函数:
int main() { int myArray[2][3] = { {1, 2, 3}, {4, 5, 6} }; printArray(myArray, 2); return 0; }
- 调用这个函数:
- 函数实现如下:
四、动态二维数组
- 使用指针和动态内存分配创建二维数组
- 可以使用
new
和delete
操作符来动态分配和释放二维数组。 - 例如:
int** dynamicArray = new int*[3]; for (int i = 0; i < 3; i++) { dynamicArray[i] = new int[4]; }
- 这里首先分配了一个指针数组,然后为每个指针分配了一个整型数组,实现了动态二维数组的创建。
- 可以使用
- 释放动态二维数组
- 释放动态二维数组时,需要先释放每个子数组,然后再释放指针数组。
for (int i = 0; i < 3; i++) { delete[] dynamicArray[i]; } delete[] dynamicArray;
- 释放动态二维数组时,需要先释放每个子数组,然后再释放指针数组。
4 条评论
-
admin SU @ 2024-12-24 19:48:44
-
使用嵌套的
for
循环遍历(最常见的方式)- 原理:
- 二维数组可以看作是由多个一维数组组成的数组。外层
for
循环用于遍历这些“一维数组”(即行),内层for
循环用于遍历每个“一维数组”中的元素(即列)。
- 二维数组可以看作是由多个一维数组组成的数组。外层
- 示例代码(以整型二维数组为例):
#include <iostream> int main() { int array[3][4] = { {1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12} }; // 外层循环遍历行 for (int i = 0; i < 3; i++) { // 内层循环遍历列 for (int j = 0; j < 4; j++) { std::cout << array[i][j] << " "; } std::cout << std::endl; } return 0; }
- 在这个例子中,
array
是一个3行4列的二维数组。外层for
循环的变量i
从0变化到2(因为数组有3行),对于每一个i
值,内层for
循环的变量j
从0变化到3(因为每行有4列)。在每次内层循环中,array[i][j]
表示当前行和列对应的元素,将其打印出来,并且在每行结束后输出一个换行符。
- 在这个例子中,
- 原理:
-
使用基于范围的
for
循环(C++11及以上)遍历(适用于简单情况)- 原理:
- C++11引入了基于范围的
for
循环,它可以简化对容器(包括数组)的遍历。对于二维数组,需要结合指针来正确遍历。可以将二维数组看作是一个指向一维数组的指针数组,通过迭代这个指针数组来访问每一行,然后再使用基于范围的for
循环遍历每行中的元素。
- C++11引入了基于范围的
- 示例代码(以整型二维数组为例):
#include <iostream> int main() { int array[3][4] = { {1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12} }; // 遍历行 for (auto& row : array) { // 遍历列 for (int element : row) { std::cout << element << " "; } std::cout << std::endl; } return 0; }
- 这里外层的基于范围的
for
循环中,row
是对array
中每行的引用(auto&
会自动推断类型为int(&)[4]
,即对包含4个整数的数组的引用)。内层的基于范围的for
循环则遍历row
中的每个元素,将其打印出来,并在每行结束后输出一个换行符。
- 这里外层的基于范围的
- 原理:
-
使用指针方式遍历(相对复杂,但更灵活)
- 原理:
- 在C++中,二维数组在内存中是按行连续存储的。可以通过一个指针先指向二维数组的起始位置,然后通过指针的算术运算来遍历数组。
- 示例代码(以整型二维数组为例):
#include <iostream> int main() { int array[3][4] = { {1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12} }; int* p = &array[0][0]; for (int i = 0; i < 3 * 4; i++) { std::cout << *(p + i) << " "; if ((i + 1) % 4 == 0) { std::cout << std::endl; } } return 0; }
- 首先,
int* p=&array[0][0];
定义了一个指针p
,它指向二维数组array
的第一个元素。然后,通过*(p + i)
来访问数组中的元素,i
从0变化到3 * 4 - 1
(因为数组总共有3 * 4
个元素)。在每次循环中打印元素,并且当i + 1
能被4整除时(即每4个元素后,也就是每行结束后)输出一个换行符。
- 首先,
- 原理:
-
-
2024-12-24 19:45:37@
C++二维数组教程
一、二维数组的概念
二维数组可以看作是一个表格,有行和列。它在逻辑上类似于矩阵,用于存储和处理具有二维结构的数据。例如,存储一个棋盘的状态、图像的像素或者学生成绩的二维表格等。
二、二维数组的定义和初始化
1. 定义二维数组
- 语法格式:
数据类型 数组名[行数][列数];
- 例如,定义一个整型的二维数组,用于存储3行4列的数据:
int myArray[3][4];
- 这里
int
是数组元素的数据类型,表示数组中的每个元素都是整数。myArray
是数组的名称,方括号中的3
表示数组有3行,4
表示每行有4个元素,即列数为4。
- 例如,定义一个整型的二维数组,用于存储3行4列的数据:
2. 初始化二维数组
- 完全初始化
- 在定义二维数组时可以同时进行初始化,将元素的值用花括号括起来,按照行的顺序依次列出元素的值。例如:
int matrix[2][3] = { {1, 2, 3}, {4, 5, 6} };
- 上面的代码定义了一个名为
matrix
的二维数组,有2行3列。第一行的元素初始化为1、2、3,第二行的元素初始化为4、5、6。
- 部分初始化
- 如果只对部分元素进行初始化,未初始化的元素会被自动初始化为0(对于基本数据类型)。例如:
int anotherMatrix[3][4] = { {1, 2}, {3}, {4, 5, 6} };
- 在这个例子中,
anotherMatrix
是一个3行4列的二维数组。第一行只初始化了前两个元素,后两个元素会被初始化为0;第二行只初始化了第一个元素,其余三个元素为0;第三行初始化了前三个元素,最后一个元素为0。
三、二维数组的访问
1. 通过下标访问元素
- 二维数组中的元素可以通过两个下标来访问,第一个下标表示行,第二个下标表示列。下标从0开始计数。例如,要访问
matrix
数组(前面定义的2行3列的数组)中第二行第三列的元素,可以使用matrix[1][2]
。注意,行下标为1表示第二行,列下标为2表示第三列。
2. 遍历二维数组
- 通常使用嵌套的循环来遍历二维数组。外层循环控制行,内层循环控制列。例如,以下代码可以遍历并打印出
matrix
数组中的所有元素:
for (int i = 0; i < 2; i++) { for (int j = 0; j < 3; j++) { std::cout << matrix[i][j] << " "; } std::cout << std::endl; }
- 外层
for
循环中,i
从0变化到1(因为数组有2行),对于每一个i
值,内层for
循环的j
从0变化到2(因为每行有3列)。在每次内层循环中,打印出当前行和列对应的元素,并在每行结束后输出一个换行符。
四、二维数组作为函数参数
1. 传递二维数组给函数
- 当把二维数组作为函数参数时,函数原型中需要指定第二维(列数)的大小,第一维(行数)可以省略。这是因为C++编译器需要知道每行的元素个数,以便正确地计算数组元素的偏移量。例如:
void printArray(int arr[][3], int rows);
- 这个函数声明表示
printArray
函数接受一个二维整型数组arr
和一个整数rows
。其中arr
的第二维大小为3,第一维大小由rows
决定。
2. 函数实现与调用
- 以下是
printArray
函数的实现,用于打印二维数组的元素:
void printArray(int arr[][3], int rows) { for (int i = 0; i < rows; i++) { for (int j = 0; j < 3; j++) { std::cout << arr[i][j] << " "; } std::cout << std::endl; } }
- 可以在
main
函数或者其他函数中调用printArray
函数,例如:
int main() { int matrix[2][3] = { {1, 2, 3}, {4, 5, 6} }; printArray(matrix, 2); return 0; }
- 在
main
函数中,定义了一个2行3列的二维数组matrix
,然后调用printArray
函数,将matrix
数组和行数2作为参数传递进去,函数会打印出数组中的所有元素。
五、动态二维数组
1. 创建动态二维数组
- 使用
new
和delete
运算符可以在堆上动态地分配二维数组。基本思路是先分配一个指针数组(用于指向每一行),然后为每个指针分配一个一维数组(代表每一行的元素)。例如,创建一个动态的3行4列的二维数组:
int** dynamicArray = new int*[3]; for (int i = 0; i < 3; i++) { dynamicArray[i] = new int[4]; }
- 首先,
new int*[3]
分配了一个包含3个指针的数组dynamicArray
,这些指针将用于指向每一行。然后,通过循环为每个指针分配一个包含4个整数的一维数组,这样就构建了一个3行4列的动态二维数组。
2. 释放动态二维数组
- 释放动态二维数组时,需要先释放每个子数组(每行的元素数组),然后再释放指针数组。例如,释放前面创建的
dynamicArray
:
for (int i = 0; i < 3; i++) { delete[] dynamicArray[i]; } delete[] dynamicArray;
- 这种释放顺序很重要,因为如果先释放了指针数组,就会丢失对每个子数组的引用,导致内存泄漏。
二维数组是C++中非常有用的数据结构,通过掌握其定义、初始化、访问、作为函数参数以及动态分配和释放的方法,可以更好地处理和组织二维结构的数据。
- 语法格式:
-
2024-12-24 19:42:30@
-
原理
- 矩阵减法与矩阵加法类似,对于两个具有相同行数和列数的矩阵(A)和(B),它们相减得到的矩阵(C),其中(C_{ij}=A_{ij}-B_{ij})。
-
代码实现
- 以下是实现矩阵减法的C++代码:
#include <iostream> #include <iomanip> // 定义矩阵的行数和列数 const int ROWS = 3; const int COLS = 3; // 矩阵减法函数 void matrixSubtraction(int A[][COLS], int B[][COLS], int C[][COLS]) { for (int i = 0; i < ROWS; i++) { for (int j = 0; j < COLS; j++) { C[i][j] = A[i][j] - B[i][j]; } } } int main() { int A[ROWS][COLS] = { {1, 2, 3}, {4, 5, 6}, {7, 8, 9} }; int B[ROWS][COLS] = { {9, 8, 7}, {6, 5, 4}, {3, 2, 1} }; int C[ROWS][COLS]; matrixSubtraction(A, B, C); // 输出结果矩阵 for (int i = 0; i < ROWS; i++) { for (int j = 0; j < COLS; j++) { std::cout << std::setw(3) << C[i][j]; } std::cout << std::endl; } return 0; }
- 在上述代码中:
- 首先定义了矩阵的行数和列数
ROWS
和COLS
。 matrixSubtraction
函数实现了矩阵减法操作,通过两个嵌套的for
循环遍历矩阵的每个元素,将A
矩阵和B
矩阵对应位置的元素相减,结果存储在C
矩阵中。- 在
main
函数中,初始化了两个矩阵A
和B
,然后调用matrixSubtraction
函数进行矩阵减法操作,最后输出结果矩阵C
。
- 首先定义了矩阵的行数和列数
-
-
2024-12-24 19:41:10@
以下是C++二维数组的一些应用实例:
一、矩阵运算
- 矩阵加法
- 矩阵加法是指对应位置的元素相加。例如,有两个矩阵A和B,它们的和C的每个元素 。
- 以下是实现矩阵加法的C++代码:
#include <iostream> #include <iomanip> const int ROWS = 3; const int COLS = 3; void matrixAddition(int A[][COLS], int B[][COLS], int C[][COLS]) { for (int i = 0; i < ROWS; i++) { for (int j = 0; j < COLS; j++) { C[i][j]=A[i][j]+B[i][j]; } } } int main() { int A[ROWS][COLS] = { {1, 2, 3}, {4, 5, 6}, {7, 8, 9} }; int B[ROWS][COLS] = { {9, 8, 7}, {6, 5, 4}, {3, 2, 1} }; int C[ROWS][COLS]; matrixAddition(A, B, C); for (int i = 0; i < ROWS; i++) { for (int j = 0; j < COLS; j++) { std::cout << std::setw(3) << C[i][j]; } std::cout << std::endl; } return 0; }
- 矩阵乘法
- 矩阵乘法的规则是:若有矩阵A()和矩阵B(),它们的乘积C()的元素 。
- 以下是实现矩阵乘法的C++代码:
#include <iostream> #include <iomanip> const int ROWS_A = 2; const int COLS_A = 3; const int ROWS_B = 3; const int COLS_B = 2; void matrixMultiplication(int A[][COLS_A], int B[][COLS_B], int C[][COLS_B]) { for (int i = 0; i < ROWS_A; i++) { for (int j = 0; j < COLS_B; j++) { C[i][j]=0; for (int k = 0; k < COLS_A; k++) { C[i][j]+=A[i][k]*B[k][j]; } } } } int main() { int A[ROWS_A][COLS_A] = { {1, 2, 3}, {4, 5, 6} }; int B[ROWS_B][COLS_B] = { {7, 8}, {9, 10}, {11, 12} }; int C[ROWS_A][COLS_B]; matrixMultiplication(A, B, C); for (int i = 0; i < ROWS_A; i++) { for (int j = 0; j < COLS_B; j++) { std::cout << std::setw(5) << C[i][j]; } std::cout << std::endl; } return 0; }
二、图像处理
- 图像灰度化
- 在图像处理中,对于彩色图像(通常用RGB表示,即红、绿、蓝三个通道),可以将其转换为灰度图像。一种简单的灰度化方法是使用平均法:。如果把图像数据存储在二维数组中(假设每个像素用一个结构体或数组表示RGB值),可以这样处理:
- 以下是简化的图像灰度化示例(假设图像是一个二维数组,每个元素表示一个像素的RGB值):
struct Pixel { int r; int g; int b; }; const int WIDTH = 100; const int HEIGHT = 100; void grayscale(Pixel image[][WIDTH]) { for (int i = 0; i < HEIGHT; i++) { for (int j = 0; j < WIDTH; j++) { int gray = (image[i][j].r + image[i][j].g + image[i][j].b) / 3; image[i][j].r = gray; image[i][j].g = gray; image[i][j].b = gray; } } }
三、棋盘游戏
- 井字棋游戏
- 井字棋游戏可以用一个二维数组来表示棋盘。例如,用0表示空白格,1表示玩家1的棋子,2表示玩家2的棋子。
- 以下是井字棋游戏棋盘表示的部分代码:
const int BOARD_SIZE = 3; int board[BOARD_SIZE][BOARD_SIZE]; // 初始化棋盘 void initializeBoard() { for (int i = 0; i < BOARD_SIZE; i++) { for (int j = 0; j < BOARD_SIZE; j++) { board[i][j]=0; } } } // 打印棋盘 void printBoard() { for (int i = 0; i < BOARD_SIZE; i++) { for (int j = 0; j < BOARD_SIZE; j++) { if (board[i][j]==0) std::cout << " - "; else if (board[i][j]==1) std::cout << " X "; else std::cout << " O "; } std::cout << std::endl; } }
- 矩阵加法
- 1