【问题标题】:Trying to swap the elements of a two dimensional array in C试图在C中交换二维数组的元素
【发布时间】:2013-04-07 22:16:14
【问题描述】:

我正在编写一个交换二维数组元素的方法。我一直在寻找这个问题的答案,但是对于这种交换似乎没有很多好的答案。与传统交换的主要区别在于,我不是在尝试交换长度为 2 的数组之一中的整数,而是尝试交换一对长度为 2 的数组,更具体地说是它们的指针。我对 C 很陌生(试图从 Java 切换)。当我编译下面的代码时,我收到一个警告“赋值使指针从没有强制转换的整数”。任何帮助将不胜感激。提前致谢。

void swap(int array[][2], int indexA, int indexB)
{
    int *temp = array[indexA];
    *array[indexA] = array[indexB];
    *array[indexB] = temp;
}

编辑:我还尝试了下面的代码来替换最后两行(不包括括号,但这导致编译器在从类型'int *分配给类型'int [2]'时给出错误“不兼容的类型” '" 对于每一行。

array[indexA] = array[indexB];
array[indexB] = temp;

编辑:数组声明如下,swap 函数作为快速排序实现的一部分被调用。调用 swap 方法的 sort 方法使用与我在 swap 中使用的相同类型的参数声明(即“int array[][2])。

int counts[256][2];

【问题讨论】:

  • 这是一个 real 二维连续数组,我们是否正确? swap 的参数表明情况确实如此,但我要澄清一下。在任何一种情况下,对数组进行值交换都需要以一种或另一种方式移动内存,除非它被埋在结构中并且值分配会为您完成。如果可能的话,你能举一个例子来说明你是如何从调用者调用这个的吗?
  • 不确定你所说的“真实”是什么意思,但我没有使用任何结构。
  • 我的意思是你没有使用指针到指针的基础。 IE。 int **base; 为您提供 2D 数组,而且您现在显然还没有发布您的调用方参数。 (这是一件好事。你的是一个真正的 2D 连续数组)。

标签: c arrays


【解决方案1】:

您的代码正在尝试对两个元素数组进行赋值,这是不允许的(对于两个元素数组,或任何其他重要的长度),除非它们被埋在结构中。

要移动数据,您有多种选择。保留现有原型,您可以执行以下操作:

void swap(int array[][2], int indexA, int indexB)
{
    int temp[2];
    memcpy(temp, array[indexA], sizeof(temp));
    memcpy(array[indexA], array[indexB], sizeof(array[indexA]));
    memcpy(array[indexB], temp, array[indexB]);
}

或者,您可以使用元素循环:

void swap(int array[][2], int indexA, int indexB)
{
    for (size_t i=0;sizeof(array[0])/sizeof(array[0][0]);++i)
    {
        int temp = array[indexA][i];
        array[indexA][i] = array[indexB][i];
        array[indexB][i] = temp;
    }
}

最后,你也可以考虑使用这样的东西:

void swap(int (*a)[2], int (*b)[2])
{
    int temp[sizeof(*a)/sizeof((*a)[0])];
    memcpy(temp,a,sizeof(temp));
    memcpy(a,b,sizeof(*a));
    memcpy(b,temp,sizeof(*b));
}

并像这样在调用方调用它:

swap(counts[indexA], counts[indexB]);

恕我直言,这更具可读性。示例如下:

#include <stdio.h>
#include <stdlib.h>

void swap(int (*a)[2], int (*b)[2])
{
    int temp[sizeof(*a)/sizeof((*a)[0])];
    memcpy(temp,a,sizeof(temp));
    memcpy(a,b,sizeof(*a));
    memcpy(b,temp,sizeof(*b));
}

int main(int argc, char *argv[])
{
    int counts[10][2];
    int indexA = 1, indexB = 2;
    counts[indexA][0] = counts[indexA][1] = 1;
    counts[indexB][0] = counts[indexB][1] = 2;
    swap(counts[indexA], counts[indexB]);

    // better be 2 2
    printf("%d %d\n", counts[indexA][0], counts[indexA][1]);
    return 0;
}

输出

2 2

【讨论】:

  • 太棒了!感谢你们俩。就像一个快速的问题一样,对于最后一次调用 memcpy,您不希望第三个参数是 sizeof(array[indexB]) 吗?
  • 我总是使用目标尺寸,尽管它们应该是相同的。如果我要 oob,我宁愿在读取大小而不是写入大小上执行此操作,但在这种情况下,这无关紧要;一切都是一样的大小。
【解决方案2】:

这应该可以解决警告,如果我理解你的情况,它会起作用。

int *temp = array[indexA];
array[indexA] = array[indexB];
array[indexB] = temp;

请记住,由于您有一个二维数组,因此“array[x]”的值仍然是一个指针。

编辑:

试试这个方法。

int temp[2];
memcpy(temp, array[indexA], sizeof(temp));
memcpy(array[indexA], array[indexB], sizeof(temp));
memcpy(array[indexB], temp, sizeof(temp));

【讨论】:

  • 我可能应该在原始帖子中写下这个,但我也尝试过这个并收到错误“错误:从类型'int *'分配给类型'int [2]'时不兼容的类型" 对于最后两行中的每一行。
  • 这不是一个指针数组。它是一个由连续值组成的真实二维数组。
  • 刚刚更新了我的答案,如果它是一个真正的二维数组,您将无法操作指针。请改用 memcpy。
  • +1,并且样本与我设计的相同并不令人惊讶。
【解决方案3】:

验证了我的情况,std::swap()可以使用:

#include <algorithm> // C++98
#include <utility> //C++11

int array[3][2] = { {1, 2}, {3, 4}, {5, 6} };
std::swap(array[0], array[2]);
// Now it's { {5, 6}, {3, 4}, {1, 2} }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-06
    • 1970-01-01
    • 2020-08-02
    • 2021-03-29
    相关资源
    最近更新 更多