MST
星途 面试题库

面试题:C++ 中二维数组作为函数参数的常见传递方式及区别

在C++ 中,若要将二维数组作为参数传递给函数,有哪些常见的传递方式?请分别举例说明,并阐述它们之间的区别。
26.5万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试

在C++ 中,将二维数组作为参数传递给函数常见的方式有以下几种:

1. 使用数组指针

#include <iostream>

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 arr[2][3] = {{1, 2, 3}, {4, 5, 6}};
    printArray(arr, 2);
    return 0;
}

这里int (*arr)[3]表示arr是一个指向包含3个int类型元素的数组的指针。必须指定第二维的大小,因为编译器需要知道如何计算偏移量来访问数组元素。

2. 使用指针的指针(不太推荐,但可以实现)

#include <iostream>

void printArray(int **arr, int rows, int cols) {
    for (int i = 0; i < rows; ++i) {
        for (int j = 0; j < cols; ++j) {
            std::cout << arr[i][j] << " ";
        }
        std::cout << std::endl;
    }
}

int main() {
    int **arr = new int*[2];
    for (int i = 0; i < 2; ++i) {
        arr[i] = new int[3];
        for (int j = 0; j < 3; ++j) {
            arr[i][j] = i * 3 + j + 1;
        }
    }
    printArray(arr, 2, 3);

    for (int i = 0; i < 2; ++i) {
        delete[] arr[i];
    }
    delete[] arr;
    return 0;
}

这种方式在内存管理上更复杂,因为需要手动分配和释放内存。并且它与传统的二维数组布局有所不同,传统二维数组是连续存储的,而这种方式每个一维数组可能在不同的内存位置。

3. 使用std::vector

#include <iostream>
#include <vector>

void printArray(const std::vector<std::vector<int>>& arr) {
    for (const auto& row : arr) {
        for (int num : row) {
            std::cout << num << " ";
        }
        std::cout << std::endl;
    }
}

int main() {
    std::vector<std::vector<int>> arr = {{1, 2, 3}, {4, 5, 6}};
    printArray(arr);
    return 0;
}

使用std::vector的好处是内存管理更加方便和安全,std::vector会自动处理内存的分配和释放。它也更具灵活性,可以动态改变大小。但性能上可能会有一些额外开销,尤其是在频繁插入和删除元素时。

区别

  • 数组指针:语法相对简洁,与传统二维数组存储方式一致,适合处理固定大小的二维数组,编译器能更好地进行优化,但需要明确指定第二维大小。
  • 指针的指针:灵活性较高,可以动态分配不同大小的一维数组,但内存管理复杂,容易出现内存泄漏,并且不具备连续存储的优势,可能影响缓存命中率。
  • std::vector:内存管理自动化,安全性高,可动态改变大小,适用于需要灵活调整大小的场景,但有一定的性能开销,尤其在处理大量数据时。