交换数组行和打印,c

时间:2011-09-25 15:35:41

标签: c multidimensional-array

这是过去两个小时里一直困扰着我的事情。我试图在二维数组中交换两行。这不是问题,但我想用一个获取指针的交换函数来做。这是我到目前为止所做的:

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

void swapRows(int **a, char **b)
{
    int *temp = *a;
    *a = *b; // WARNING #1
    *b = temp; // WARNING #1

}

void print(int a[][2],int rows,int cols)
{
    int i,j;
    for (i=0; i<rows; i++)
    {
        for (j=0; j<rows; j++)
        {
            printf("%d ",a[i][j]);
        }
        printf("\n");
    }
}

int main(void)
{
    int matrix[2][2] = {{1,2},{3,4}};
    print(matrix,2,2);
    swapRows(&matrix[0],&matrix[1]); //WARNING #2
    print(matrix,2,2);
    return EXIT_SUCCESS;
}

所以,这是我的问题:

1)交换函数只在每个数组的第一个元素之间交换,这是有道理的。如何让它交换其他元素?我是否需要迭代整行?

2)声明打印时,只有在设置a[][]2时才有效。在此之前,我尝试编写int **arr,但我遇到了分段错误。这是为什么?另外,为什么我必须在数组参数中指定cols的数量?我有行和列,编译器为什么强迫我这样做?

3)最后,使用此版本的print()我收到编译器passing argument 2 of ‘swapRows’ from incompatible pointer type的警告(代码中的警告#2),我收到另一个警告(#1):{{1}在assignment from incompatible pointer type中。这是为什么? 提前谢谢!

2 个答案:

答案 0 :(得分:3)

你困惑的根源:

的类型
int m1[2][2]; // a *single* block of memory of size 2*2*sizeof(int)
              //
              // this is a *real* 2d-array

相同
int **m2;  // a pointer of size sizeof(int*) almost certainly the 
           // equal to sizeof(void*)
           //
           // This could be made to point at at least two logically 
           // distinct blocks of memory and *act* like a 2d-array

是的,m2(指向指针的指针)可以使用[][]取消引用,但是m1(实际的二维数组) < em>不能 **取消引用。

这意味着您调用交换行是一个可怕的错误。看看为什么......

  • matrix[0]是第一个子数组(和int[2]包含{1,2}),取其地址为空操作,获取矩阵[0] [0]的地址,这是内存中包含1整数表示的一个点(这是一个指向int的指针)。
  • 类似的参数适用于&matrix[1]它指向包含2的内存。

你调用swapRows认为这些参数是指向指针的指针(它们不是,所以你的编译器会发出警告)。它会运行,因为指向int的指针与指向指针指针的指针大小相同(不是严格保证,但你通常会侥幸逃脱它)。它运行时的作用是将a的点到大小的内容与指向{int}的内容大小b交换。如果恰好是sizeof(int) == sizeof(int*)(这种情况并非罕见),则相当于matix[0][0]matrix[1][0]进行交换。

这不是你想要的。

你能做些什么?

  • matrix声明为指向指针,并将内存分配为不规则数组,然后使用现有交换
  • matrix声明为指针数组并为行分配内存,然后使用现有的交换
  • 保留matrix的现有声明并重新写入交换以交换每个值。
  • 保留matrix的现有声明,但也提供一个存取指针数组,使用访问器上的现有交换,并始终使用访问器(前两个选项的唯一可能优势是一切都在堆栈上。)
  • 使用row-as-a-structure hack。

行作为一种结构

考虑一下

typedef struct {
   int r[2];
} row_t;
row_t m3[2];

m3是一个结构数组,每个结构都是int的数组。访问是一个小问题:m3[i].r[j]你可以做

row_t temp = m3[n];
m3[n] = m3[m];
m3[m] = temp;

交换行。

答案 1 :(得分:0)

数组和指针是不同的东西,尽管C使它们在许多情况下表现相似。您还意外地使用char而不是int作为第二个参数。你的swapRows函数应该像这样声明:

void swapRows(int (*a)[2], int (*b)[2])

您需要将(* a)[0]与(* b)[0]和(* a)[1]交换为(* b)[1]。

C正在将数组转换为指针(带有警告),但在这种情况下这会让人感到困惑。

只是C的限制,数组必须具有编译时已知的大小。