一、二维数组的定义

在C++中,二维数组是一种数据结构,它可以被看作是一个具有行和列的表格。

  1. 语法格式

    • 二维数组的声明语法如下:
      数据类型 数组名[行数][列数];
      
    • 例如,要声明一个整型的二维数组,有3行4列,可以这样写:
      int myArray[3][4];
      
    • 这里,int是数据类型,表示数组中的元素是整型,myArray是数组名,3表示行数,4表示列数。
  2. 初始化

    • 二维数组可以在声明时进行初始化。
    • 完全初始化:
      int myArray[2][3] = {
          {1, 2, 3},
          {4, 5, 6}
      };
      
      • 这里第一行的元素是123,第二行的元素是456
    • 部分初始化:
      int myArray[2][3] = {
          {1, 2},
          {3}
      };
      
      • 对于未初始化的元素,C++会自动将其初始化为0。所以在这个例子中,第一行的第三个元素和第二行的后两个元素都将是0。

二、二维数组的访问

  1. 通过下标访问
    • 可以使用两个下标来访问二维数组中的元素,第一个下标表示行,第二个下标表示列。
    • 例如,要访问上面myArray数组中第二行第三列的元素,可以这样写:
      int element = myArray[1][2];
      
      • 注意,下标是从0开始计数的,所以第二行对应的下标是1,第三列对应的下标是2
  2. 遍历二维数组
    • 使用嵌套的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循环控制列,这样就可以逐个访问数组中的元素并进行操作,如打印出来。

三、二维数组作为函数参数

  1. 传递二维数组给函数
    • 当把二维数组作为函数参数时,函数原型需要指定数组的第二维大小。第一维大小可以省略。
    • 例如:
      void printArray(int arr[][3], int rows);
      
      • 这里arr是二维数组参数,3是列数,rows是行数参数。
  2. 函数实现示例
    • 函数实现如下:
      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;
        }
        

四、动态二维数组

  1. 使用指针和动态内存分配创建二维数组
    • 可以使用newdelete操作符来动态分配和释放二维数组。
    • 例如:
      int** dynamicArray = new int*[3];
      for (int i = 0; i < 3; i++) {
          dynamicArray[i] = new int[4];
      }
      
      • 这里首先分配了一个指针数组,然后为每个指针分配了一个整型数组,实现了动态二维数组的创建。
  2. 释放动态二维数组
    • 释放动态二维数组时,需要先释放每个子数组,然后再释放指针数组。
      for (int i = 0; i < 3; i++) {
          delete[] dynamicArray[i];
      }
      delete[] dynamicArray;
      

4 条评论

  • @ 2024-12-24 19:48:44
    1. 使用嵌套的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]表示当前行和列对应的元素,将其打印出来,并且在每行结束后输出一个换行符。
    2. 使用基于范围的for循环(C++11及以上)遍历(适用于简单情况)

      • 原理
        • C++11引入了基于范围的for循环,它可以简化对容器(包括数组)的遍历。对于二维数组,需要结合指针来正确遍历。可以将二维数组看作是一个指向一维数组的指针数组,通过迭代这个指针数组来访问每一行,然后再使用基于范围的for循环遍历每行中的元素。
      • 示例代码(以整型二维数组为例)
        #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中的每个元素,将其打印出来,并在每行结束后输出一个换行符。
    3. 使用指针方式遍历(相对复杂,但更灵活)

      • 原理
        • 在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。

      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. 创建动态二维数组

      • 使用newdelete运算符可以在堆上动态地分配二维数组。基本思路是先分配一个指针数组(用于指向每一行),然后为每个指针分配一个一维数组(代表每一行的元素)。例如,创建一个动态的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
        1. 原理

          • 矩阵减法与矩阵加法类似,对于两个具有相同行数和列数的矩阵(A)和(B),它们相减得到的矩阵(C),其中(C_{ij}=A_{ij}-B_{ij})。
        2. 代码实现

          • 以下是实现矩阵减法的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;
        }
        
        • 在上述代码中:
          • 首先定义了矩阵的行数和列数ROWSCOLS
          • matrixSubtraction函数实现了矩阵减法操作,通过两个嵌套的for循环遍历矩阵的每个元素,将A矩阵和B矩阵对应位置的元素相减,结果存储在C矩阵中。
          • main函数中,初始化了两个矩阵AB,然后调用matrixSubtraction函数进行矩阵减法操作,最后输出结果矩阵C
        • @ 2024-12-24 19:41:10

          以下是C++二维数组的一些应用实例:

          一、矩阵运算

          1. 矩阵加法
            • 矩阵加法是指对应位置的元素相加。例如,有两个矩阵A和B,它们的和C的每个元素 Cij=Aij+BijC_{ij}=A_{ij}+B_{ij}
            • 以下是实现矩阵加法的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;
              }
              
          2. 矩阵乘法
            • 矩阵乘法的规则是:若有矩阵A(m×nm\times n)和矩阵B(n×pn\times p),它们的乘积C(m×pm\times p)的元素 Cij=k=0n1AikBkjC_{ij}=\sum_{k = 0}^{n-1}A_{ik}B_{kj}
            • 以下是实现矩阵乘法的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;
              }
              

          二、图像处理

          1. 图像灰度化
            • 在图像处理中,对于彩色图像(通常用RGB表示,即红、绿、蓝三个通道),可以将其转换为灰度图像。一种简单的灰度化方法是使用平均法:Gray=(R+G+B)/3Gray=(R + G + B)/3。如果把图像数据存储在二维数组中(假设每个像素用一个结构体或数组表示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;
                      }
                  }
              }
              

          三、棋盘游戏

          1. 井字棋游戏
            • 井字棋游戏可以用一个二维数组来表示棋盘。例如,用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