MST
星途 面试题库

面试题:C++ 多维数组指针在函数参数传递中的应用

编写一个函数,该函数接收一个三维数组`int threeD[2][3][4];`的指针作为参数,在函数内部实现对三维数组的转置(即将`threeD[i][j][k]`转换为`threeD[k][j][i]`),并返回转置后的数组指针。请阐述在函数参数传递过程中需要注意的指针类型匹配和内存管理问题。
26.6万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试
#include <iostream>

// 函数声明
int (*transpose(int (*threeD)[3][4]))[3][2];

int main() {
    int threeD[2][3][4] = {
        {
            {1, 2, 3, 4},
            {5, 6, 7, 8},
            {9, 10, 11, 12}
        },
        {
            {13, 14, 15, 16},
            {17, 18, 19, 20},
            {21, 22, 23, 24}
        }
    };

    int (*transposed)[3][2] = transpose(threeD);

    // 输出转置后的数组
    for (int k = 0; k < 4; ++k) {
        for (int j = 0; j < 3; ++j) {
            for (int i = 0; i < 2; ++i) {
                std::cout << transposed[k][j][i] << " ";
            }
            std::cout << std::endl;
        }
        std::cout << std::endl;
    }

    return 0;
}

// 函数定义
int (*transpose(int (*threeD)[3][4]))[3][2] {
    static int transposed[4][3][2];

    for (int i = 0; i < 2; ++i) {
        for (int j = 0; j < 3; ++j) {
            for (int k = 0; k < 4; ++k) {
                transposed[k][j][i] = threeD[i][j][k];
            }
        }
    }

    return transposed;
}

指针类型匹配

  1. 参数指针类型:函数接收一个指向int [3][4]的指针,因为三维数组名在传递给函数时会退化为指向其首元素的指针,而threeD的首元素类型是int [3][4]
  2. 返回指针类型:函数返回一个指向int [3][2]的指针,因为转置后的数组类型为int [4][3][2],返回的指针指向该数组的首元素,其类型为int [3][2]

内存管理问题

  1. 静态数组:这里使用静态数组transposed来存储转置后的结果。静态数组的生命周期与程序相同,在函数调用结束后不会被销毁,保证了返回的指针始终有效。
  2. 动态内存分配:如果不使用静态数组,也可以使用动态内存分配(如new运算符)来创建转置后的数组。但这样做需要在调用者中负责释放内存,以避免内存泄漏。例如:
int (*transpose(int (*threeD)[3][4]))[3][2] {
    int (*transposed)[3][2] = new int[4][3][2];

    for (int i = 0; i < 2; ++i) {
        for (int j = 0; j < 3; ++j) {
            for (int k = 0; k < 4; ++k) {
                transposed[k][j][i] = threeD[i][j][k];
            }
        }
    }

    return transposed;
}

在调用者中使用完后需要使用delete[]来释放内存:

int main() {
    int threeD[2][3][4];
    int (*transposed)[3][2] = transpose(threeD);
    // 使用 transposed
    delete[] transposed;
    return 0;
}

使用动态内存分配需要更谨慎的内存管理,而静态数组虽然简单,但如果函数多次调用,可能会导致数据覆盖问题,需要根据具体需求选择合适的方法。