在C中交换多维数组的子数组

时间:2021-09-12 12:17:46

I have a 50 x 50 matrix arr[50][50] and need to swap the values in the sub-array arr[0] and arr[1]. ie, the whole 50 elements in each sub-array need to be swapped.

我有一个50 x 50矩阵arr [50] [50],需要交换子数组arr [0]和arr [1]中的值。即,需要交换每个子阵列中的整个50个元素。

The only way I can think of to do this is by using a loop like:

我能想到的唯一方法是使用如下循环:

for(i=0; i<50; ++i)
{
    int t = arr[0][i];
    arr[0][i] = arr[1][i];
    arr[1][i] = t;
}

I was wondering if there were any simpler or shorter methods? Using pointers maybe?

我想知道是否有更简单或更短的方法?使用指针可能吗?

I tried things like

我尝试过类似的东西

int *t = arr[0];
arr[0] = arr[1];
arr[1] = t;

but it gave error at the first line about "incompatible types when assigning to type 'int[2]' from type 'int *' ".

但它在第一行给出了错误“从类型'int *'”分配到类型'int [2]'时的不兼容类型。

Then I tried pointer to an array

然后我尝试指向数组的指针

int (*t)[50] = arr[0];
arr[0] = arr[1];
arr[1] = t;

This time I got error at the second line about "incompatible types when assigning to type 'int[50]' from type 'int *' ".

这次我在第二行有关“从类型'int *'”分配类型'int [50]'时出现“不兼容类型”时出错。

3 个解决方案

#1


4  

If your matrix is implemented as arr[50][50] then the only way to physically swap two rows is to physically exchange data in memory. Your cycle is one way to do it. The rest would be just variations of that approach. You can swap matrix elements one-by-one (your cycle), you can swap the entire rows using an intermediate row-sized buffer (memcpy approach). All of them still do the same thing. There's no way around it.

如果您的矩阵实现为arr [50] [50],那么物理交换两行的唯一方法是在内存中物理交换数据。你的周期是一种方法。剩下的就是这种方法的变化。您可以逐个交换矩阵元素(您的周期),您可以使用中间行大小的缓冲区(memcpy方法)交换整个行。他们所有人仍然做同样的事情。没有办法绕过它。

If your array were implemented differently - say, a "jagged" array implemented as array of pointers to sub-arrays, then you would be able to just swap two pointers and be done with it. But in case of arr[50][50] it is not possible.

如果你的数组以不同的方式实现 - 比如,一个“锯齿状”数组实现为指向子数组的指针数组,那么你就可以只交换两个指针并完成它。但是在arr [50] [50]的情况下,这是不可能的。

If you wish, you can just "convert" your current array into a "jagged" version by a separate row-pointer array. That row-pointer array will now become your matrix a, while the original a[50][50] will become a_data

如果您愿意,您可以通过单独的行指针数组将当前数组“转换”为“锯齿状”版本。那个行指针数组现在将成为你的矩阵a,而原来的[50] [50]将成为a_data

int a_data[50][50];

int *a[50];
for (unsigned i = 0; i < 50; ++i)
  a[i] = a_data[i];

/* Fill the matrix */
for (unsigned i = 0; i < 50; ++i)
  for (unsigned j = 0; j < 50; ++j)
    a[i][j] = rand();

/* Print the matrix */
for (unsigned i = 0; i < 50; ++i)
{
  for (unsigned j = 0; j < 50; ++j)
    printf("%d ", a[i][j]);
  printf("\n");
}

/* Swap the rows */
int *temp = a[0];
a[0] = a[1];
a[1] = temp;

/* Print the matrix */
for (unsigned i = 0; i < 50; ++i)
{
  for (unsigned j = 0; j < 50; ++j)
    printf("%d ", a[i][j]);
  printf("\n");
}

Note, that despite the physical structure of a is now different, you can still use a[i][j] syntax to work with it.

请注意,尽管a的物理结构现在不同,但您仍然可以使用[i] [j]语法来处理它。

#2


1  

As explained in the comments, and within the other answers, in order to swap rows of an actual 2D array (as apposed to an array of pointers), you must copy/move the data from the source to target row in memory. The most straight forward way to approach this is either with a loop to copy element-by-element to temporary storage to effect the swap, or use the memory copy functions provided by the C-library (e.g. memcpy or memmove). A simple implementation using memcopy (shown with a 3x10 array for array for purposes of the example) would be:

正如在注释中所解释的那样,在其他答案中,为了交换实际2D数组的行(与指针数组相对应),您必须将数据从源复制/移动到内存中的目标行。最直接的方法是使用循环将元素逐个元素复制到临时存储以实现交换,或者使用C库提供的内存复制功能(例如memcpy或memmove)。使用memcopy的简单实现(为了示例的目的,使用3x10数组显示数组)将是:

#include <stdio.h>
#include <string.h>

enum { ROW = 3, COL = 10 };

void swaprow (int (*a)[COL], int c1, int c2);
void prna (int (*a)[COL]);

int main (void) {

    int a[ROW][COL] = {{0}};

    for (int i = 0; i < ROW; i++)
        for (int j = 0; j < COL; j++)
            a[i][j] = i;

    prna (a);
    swaprow (a, 0, 1);
    putchar ('\n');
    prna (a);

    return 0;
}

void swaprow (int (*a)[COL], int c1, int c2)
{
    int tmp[COL];

    memcpy (tmp, a[c1], COL * sizeof *tmp);
    memcpy (a[c1], a[c2], COL * sizeof *a[c1]);
    memcpy (a[c2], tmp, COL * sizeof *a[c2]);
}

void prna (int (*a)[COL])
{
    for (int i = 0; i < ROW; i++) {
        for (int j = 0; j < COL; j++)
            printf ("%2d", a[i][j]);
        putchar ('\n');
    }

}

Example Use/Output

$ ./bin/array2d_swap_row
 0 0 0 0 0 0 0 0 0 0
 1 1 1 1 1 1 1 1 1 1
 2 2 2 2 2 2 2 2 2 2

 1 1 1 1 1 1 1 1 1 1
 0 0 0 0 0 0 0 0 0 0
 2 2 2 2 2 2 2 2 2 2

Look things over and let me know if you have any questions.

仔细看看,如果您有任何疑问,请告诉我。

#3


0  

You will have to copy the data to be swapped with memcpy, I have provided sample to program to show how you can do it(ie swap arr[0] and arr[1]).

您将不得不复制要与memcpy交换的数据,我已经提供了示例程序来展示如何做到这一点(即交换arr [0]和arr [1])。

int main(void) {
    // your code goes here
    int t[3];
    int arr[3][3]={{1,2,3},{4,5,6},{7,8,9}};
    printf("\n%d %d %d",arr[0][0],arr[0][1],arr[0][2]);
    printf("\n%d %d %d",arr[1][0],arr[1][1],arr[1][2]);
    memcpy(t,arr[0],sizeof(t));
    memcpy(arr[0],arr[1],sizeof(t));
    memcpy(arr[1],t,sizeof(t));
    printf("\n%d %d %d",arr[0][0],arr[0][1],arr[0][2]);
    printf("\n%d %d %d",arr[1][0],arr[1][1],arr[1][2]);
    return 0;
}

#1


4  

If your matrix is implemented as arr[50][50] then the only way to physically swap two rows is to physically exchange data in memory. Your cycle is one way to do it. The rest would be just variations of that approach. You can swap matrix elements one-by-one (your cycle), you can swap the entire rows using an intermediate row-sized buffer (memcpy approach). All of them still do the same thing. There's no way around it.

如果您的矩阵实现为arr [50] [50],那么物理交换两行的唯一方法是在内存中物理交换数据。你的周期是一种方法。剩下的就是这种方法的变化。您可以逐个交换矩阵元素(您的周期),您可以使用中间行大小的缓冲区(memcpy方法)交换整个行。他们所有人仍然做同样的事情。没有办法绕过它。

If your array were implemented differently - say, a "jagged" array implemented as array of pointers to sub-arrays, then you would be able to just swap two pointers and be done with it. But in case of arr[50][50] it is not possible.

如果你的数组以不同的方式实现 - 比如,一个“锯齿状”数组实现为指向子数组的指针数组,那么你就可以只交换两个指针并完成它。但是在arr [50] [50]的情况下,这是不可能的。

If you wish, you can just "convert" your current array into a "jagged" version by a separate row-pointer array. That row-pointer array will now become your matrix a, while the original a[50][50] will become a_data

如果您愿意,您可以通过单独的行指针数组将当前数组“转换”为“锯齿状”版本。那个行指针数组现在将成为你的矩阵a,而原来的[50] [50]将成为a_data

int a_data[50][50];

int *a[50];
for (unsigned i = 0; i < 50; ++i)
  a[i] = a_data[i];

/* Fill the matrix */
for (unsigned i = 0; i < 50; ++i)
  for (unsigned j = 0; j < 50; ++j)
    a[i][j] = rand();

/* Print the matrix */
for (unsigned i = 0; i < 50; ++i)
{
  for (unsigned j = 0; j < 50; ++j)
    printf("%d ", a[i][j]);
  printf("\n");
}

/* Swap the rows */
int *temp = a[0];
a[0] = a[1];
a[1] = temp;

/* Print the matrix */
for (unsigned i = 0; i < 50; ++i)
{
  for (unsigned j = 0; j < 50; ++j)
    printf("%d ", a[i][j]);
  printf("\n");
}

Note, that despite the physical structure of a is now different, you can still use a[i][j] syntax to work with it.

请注意,尽管a的物理结构现在不同,但您仍然可以使用[i] [j]语法来处理它。

#2


1  

As explained in the comments, and within the other answers, in order to swap rows of an actual 2D array (as apposed to an array of pointers), you must copy/move the data from the source to target row in memory. The most straight forward way to approach this is either with a loop to copy element-by-element to temporary storage to effect the swap, or use the memory copy functions provided by the C-library (e.g. memcpy or memmove). A simple implementation using memcopy (shown with a 3x10 array for array for purposes of the example) would be:

正如在注释中所解释的那样,在其他答案中,为了交换实际2D数组的行(与指针数组相对应),您必须将数据从源复制/移动到内存中的目标行。最直接的方法是使用循环将元素逐个元素复制到临时存储以实现交换,或者使用C库提供的内存复制功能(例如memcpy或memmove)。使用memcopy的简单实现(为了示例的目的,使用3x10数组显示数组)将是:

#include <stdio.h>
#include <string.h>

enum { ROW = 3, COL = 10 };

void swaprow (int (*a)[COL], int c1, int c2);
void prna (int (*a)[COL]);

int main (void) {

    int a[ROW][COL] = {{0}};

    for (int i = 0; i < ROW; i++)
        for (int j = 0; j < COL; j++)
            a[i][j] = i;

    prna (a);
    swaprow (a, 0, 1);
    putchar ('\n');
    prna (a);

    return 0;
}

void swaprow (int (*a)[COL], int c1, int c2)
{
    int tmp[COL];

    memcpy (tmp, a[c1], COL * sizeof *tmp);
    memcpy (a[c1], a[c2], COL * sizeof *a[c1]);
    memcpy (a[c2], tmp, COL * sizeof *a[c2]);
}

void prna (int (*a)[COL])
{
    for (int i = 0; i < ROW; i++) {
        for (int j = 0; j < COL; j++)
            printf ("%2d", a[i][j]);
        putchar ('\n');
    }

}

Example Use/Output

$ ./bin/array2d_swap_row
 0 0 0 0 0 0 0 0 0 0
 1 1 1 1 1 1 1 1 1 1
 2 2 2 2 2 2 2 2 2 2

 1 1 1 1 1 1 1 1 1 1
 0 0 0 0 0 0 0 0 0 0
 2 2 2 2 2 2 2 2 2 2

Look things over and let me know if you have any questions.

仔细看看,如果您有任何疑问,请告诉我。

#3


0  

You will have to copy the data to be swapped with memcpy, I have provided sample to program to show how you can do it(ie swap arr[0] and arr[1]).

您将不得不复制要与memcpy交换的数据,我已经提供了示例程序来展示如何做到这一点(即交换arr [0]和arr [1])。

int main(void) {
    // your code goes here
    int t[3];
    int arr[3][3]={{1,2,3},{4,5,6},{7,8,9}};
    printf("\n%d %d %d",arr[0][0],arr[0][1],arr[0][2]);
    printf("\n%d %d %d",arr[1][0],arr[1][1],arr[1][2]);
    memcpy(t,arr[0],sizeof(t));
    memcpy(arr[0],arr[1],sizeof(t));
    memcpy(arr[1],t,sizeof(t));
    printf("\n%d %d %d",arr[0][0],arr[0][1],arr[0][2]);
    printf("\n%d %d %d",arr[1][0],arr[1][1],arr[1][2]);
    return 0;
}