【问题标题】:Passing and modifying mutlidimensional arrays in C/C++在 C/C++ 中传递和修改多维数组
【发布时间】:2012-04-25 23:23:47
【问题描述】:

我在使用数组和指针时遇到问题,虽然我很瘦,但我知道自己做错了什么,但我无法找到简单的解决方案。

我有这段代码:

void faceRotateACW(char *face[CUBE_DIM][CUBE_DIM]){
    char tempFace[CUBE_DIM][CUBE_DIM];
    for (int y=0;y<CUBE_DIM;y++){
        for (int x=0;x<CUBE_DIM;x++){
            tempFace[y][CUBE_DIM-x]=face[x][y];
        }
    }
    for (int a=0;a<CUBE_DIM;a++){
        for (int b=0;b<CUBE_DIM;b++){
            face[a][b]=tempFace[a][b];
        }
    }
}

现在我知道问题在于我正在尝试将 char 指针分配给 char,这是不行的,但是我如何复制,然后修改数组并将其推回传递的数组参考?如何获取要传递给函数的数组中的值?

好的,一切顺利,至少我现在开始更好地理解这个问题(谢谢大家)。我需要提供更多信息,因为我使用此功能的方式可能也不是最好的方式,让我澄清一下。

我将数组定义为:

char *faces[NUM_FACES][CUBE_DIM][CUBE_DIM]={{{"o","o","o"},{"o","o","o"},{"o","o","o"}},
        {{"o","o","o"},{"o","o","o"},{"o","o","o"}},
        {{"o","o","o"},{"o","o","o"},{"o","o","o"}},
        {{"o","o","o"},{"o","o","o"},{"o","o","o"}},
        {{"o","o","o"},{"o","o","o"},{"o","o","o"}},
        {{"o","o","o"},{"o","o","o"},{"o","o","o"}}}; 

但是,当我调用该函数时,我试图像这样剥离外部数组:

 faceRotateACW(faces[currentFace]);

对不起,我是第一次发帖:)

【问题讨论】:

  • 不太清楚你想做什么 - 你想传递一个字符指针数组(也就是矩阵)并简单地在你的矩阵中交换这些字符指针吗?如果是这样,为什么要创建字符矩阵而不是字符指针矩阵?
  • 我正在尝试传入矩阵值,旋转它们并替换传入的值。我传递的是指针而不是矩阵中的值吗?
  • 问题是这些值实际上是什么。值是chars 还是char *s?如果他们是chars,请阅读 Johns 的答案,如果他们是 char *s,请阅读 dbaupps 和 Yakovs 的答案。或者我在开玩笑 - 阅读所有答案! ;)
  • @PhilHolden - 所以你的参数是二维字符串数组,签名是 ->void faceRotateACW(char* face[CUBE_DIM][CUBE_DIM]) 我的解决方案处理这种情况

标签: c arrays pointers multidimensional-array pass-by-reference


【解决方案1】:

让我们从头开始。

在您的main 函数(或任何调用faceRotateACW 的人)中,您有一个类似

char theFace[CUBE_DIM][CUBE_DIM];

除非它是 sizeof 或一元 &amp; 运算符的操作数,或者是用于在声明中初始化另一个数组的字符串字面量,否则是“T 的 N 元素数组”类型的表达式将被转换为/替换为/“衰减”为“指向T的指针”类型的表达式,其值为数组第一个元素的地址。

如果你把你的函数称为

rotateFaceACW(theFace);

函数调用中的表达式theFace 将替换为“指向char 的CUBE_DIM 元素数组的指针”或char (*)[CUBE_DIM] 类型的表达式。因此,您的函数原型需要看起来像

void rotateFaceACW(char (*face)[CUBE_DIM]) {...}

void rotateFaceACW(char face[][CUBE_DIM]) {...}

在这种情况下是一样的。您可以将其视为函数中的普通数组:

void rotateFaceACW(char (*face)[CUBE_DIM])
{
  char tempFace[CUBE_DIM][CUBE_DIM];
  ...
      tempFace[y][(CUBE_DIM-1)-x] = face[x][y];  // thanks Anthales
  ...
      face[x][y] = tempFace[x][y];

由于face 是指向数组theFace 的第一个元素的指针,因此在rotateFaceACW 中所做的任何更改都将反映在theFace 中。

由于您似乎总是要处理大小为常数 (CUBE_DIM) 的 NxN 矩阵,您可能不需要显式传递行数,但在一般情况下你需要。

如果您想处理 任何 行和列数的二维数组,您将不得不采用不同的方法,我不会在这里讨论,因为它看起来不像与您的问题相关。

【讨论】:

  • 添加关于写作CUBE_DIM-1-x而不是CUBE_DIM-x的强制性评论。
  • 在我阅读 Yakovs 的答案之前,我什至没有看到溢出,所以请不要相信我 ;)
【解决方案2】:

据我了解,您尝试“以相反的列顺序”转置字符串矩阵。 以下实现在 O(1) 空间和 O(CUBE_DIM^2) 时间完成

void faceRotateACW(char* face[CUBE_DIM][CUBE_DIM])
{
    for (int i = 0;i< CUBE_DIM;++i) {
        for (int j = i; j<CUBE_DIM;++j) {
            char* tmpFace = face[i][j];
            face[i][j] = face[j][i];
            face[j][i] = tmpFace;
        }
        for (int j = 0;j < CUBE_DIM/2;++j) {
            char* tmpFace = face[i][j];
            face[i][j] = face[i][CUBE_DIM - 1 - j];
            face[i][CUBE_DIM - 1 - j] = tmpFace;
        }
    }

}

【讨论】:

  • 这是一个更好用的算法,但它实际上并不能回答问题,因为face 只包含chars 而不是char*s。
  • @dbaupp - 所以当他得到一个指向这个矩阵的指针时,他必须“转置”字符的二维矩阵?
  • 我相信,在将char* face 替换为char (*face),将face 替换为(*face) 以及将char* tmpFace 替换为char tmpFace 之后,您的代码是正确的。
  • @dbaupp-请看他的评论——参数是二维字符串数组
  • 是的,我看到了,这就是我最近的评论所指的。
【解决方案3】:

你应该使用指针数组。语法将是这样的 faceRotateACW(char *face[],int cube_dim) 然后您可以访问多维数组中的所有值,然后更改这些值。

【讨论】:

    【解决方案4】:

    正如你所定义的,你传递了一个CUBE_DIM×CUBE_DIM矩阵指向chars,不是一个指向CUBE_DIM×CUBE_DIM矩阵的指针chars。要解决此问题,您应该使用

    char (*face)[CUBE_DIM][CUBE_DIM]
    

    表示face 是指针,而不是存储在数组中的值。完成此操作后,代码将不再编译,因为face[x][y](它是char[])是错误的类型,分配给tempFace[_][_]char)是错误的类型。

    你可以看出这一点,因为face[x] 取消引用了face 的外层指针(偏移量为x),因此类型char[][] 也是如此。 [y] 现在剥离了一层[],所以face[x][y] 的类型是char[]不是 char

    要解决这个问题,我们需要在开始索引之前获取face 指向的数组,即我们需要取消引用face 然后索引。那就是:

    (*face)[x][y]
    

    所以最后的代码是:

    void faceRotateACW(char (*face)[CUBE_DIM][CUBE_DIM]){
        char tempFace[CUBE_DIM][CUBE_DIM];
        for (int y=0;y<CUBE_DIM;y++){
            for (int x=0;x<CUBE_DIM;x++){
                tempFace[y][CUBE_DIM-1-x]=(*face)[x][y];
            }
        }
        for (int a=0;a<CUBE_DIM;a++){
            for (int b=0;b<CUBE_DIM;b++){
                (*face)[a][b]=tempFace[a][b];
            }
        }
    }
    

    【讨论】:

    • 如果mat 被声明为char mat[CUBE_DIM][CUBE_DIM],则可能会添加对这个函数的调用看起来像faceRotateACW(&amp;mat)。第一个循环也有溢出;应该是CUBE_DIM-1-x
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-09-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-22
    • 2016-03-19
    • 1970-01-01
    相关资源
    最近更新 更多