交换数组行并打印,c

发布于 2024-12-06 09:57:10 字数 1073 浏览 0 评论 0原文

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

#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)声明 print 时,仅当我设置 a[][]2 时,它才有效。在此之前,我尝试编写 int **arr 但出现分段错误。这是为什么?另外,为什么我必须指定数组参数中的列数?我有行和列,为什么编译器强迫我这样做?

3)最后,使用这个版本的print(),我收到编译器的警告正在从不兼容的指针类型传递'swapRows'的参数2(代码中的警告#2) ),我收到另一个警告(#1):swapRows() 中的分配来自不兼容的指针类型。这是为什么? 提前致谢!

this is something that's been bugging me for the past two hours. I'm trying to swap two rows in a two dimensional array. This is not a problem, but I want to do it with a swap function that gets pointers. Here's what I have so far:

#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;
}

So, here are my questions:

1)The swap functions only swaps between the first elements in each array, which makes sense. How do I get it to swap the other elements? Do I HAVE to iterate the entire row?

2)When declaring print it only worked if i set a[][]2. Before that I tried writing int **arr but I had a segmentation fault. Why is that? Also, why must I specify the number of cols in the array argument? I have rows and cols for that, why does the compiler forces me to do so?

3)finally, using this version of print() I get a warning from the compiler passing argument 2 of ‘swapRows’ from incompatible pointer type (warning #2 in the code) and I get another warning (#1) : assignment from incompatible pointer type in swapRows(). Why is that?
Thanks in advance!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

乞讨 2024-12-13 09:57:10

困惑的根源:

的类型

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

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

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

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

您调用的 swapRows 认为这些参数是指向 int 的指针(它们不是,因此您的编译器会抛出警告)。但它会运行,因为指向 int 的指针与指向 int 的指针的大小相同(这并不能严格保证,但通常会逃脱它)。它运行时的作用是将a 的指针到int 大小的内容与b 的指针到int 大小的内容交换。如果碰巧出现 sizeof(int) == sizeof(int*) (这并不罕见),这将相当于交换 matix[0][0]代码>与矩阵[1][0]

那不是你想要的。

你能做些什么呢?

  • 将矩阵声明为指向指针的指针,并像在参差不齐的数组中一样分配内存,然后使用现有的交换区
  • 将矩阵声明为指针数组并为行分配内存,然后使用现有的交换
  • 保留矩阵的现有声明并重写交换以交换每个值。
  • 保留矩阵的现有声明,但还提供指针的访问器数组,在访问器上使用现有的交换,并始终使用访问器(与前两个选项相比,此选项唯一可能的优点是一切都驻留在堆栈上)。
  • 使用行作为结构的技巧。

行作为结构

考虑此

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

m3 是一个结构数组,每个结构都是一个 int 数组。 Access 是一个小 awkword:m3[i].r[j]但是你可以

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

交换行。

The source of your confusion:

The type of

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

is not the same as that of

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

Yes, m2 (pointer to a pointer) can be dereferenced using [][], but m1 (a actual two dimensional array) can not be dereferenced with **.

This means that your call to swap rows is a horrible error. Look why...

  • matrix[0] is the first sub array (and int[2] containing {1,2}), taking the address of it is a null operation that gets the address of matrix[0][0], which is a spot in memory containing the integer representation of 1 (that is this is a pointer-to-int).
  • A similar argument applies to &matrix[1] it points a memory containing 2.

The you call swapRows which thinks that these arguments are pointers-to-pointers-to-int (which they are not, so your compiler throws a warning). It will run though because a pointer-to-int is the same size as a pointer-to-pointer-to-int (that isn't strictly guaranteed, but you'll usually get away with it). What it does when it runs is swap the point-to-int sized contents of a with the pointer-to-int sized contents of b. If it happens to be the case that sizeof(int) == sizeof(int*) (which is not uncommon), this will amount to swapping matix[0][0] with matrix[1][0].

That is not what you wanted.

What can you do about it?

  • Declare matrix as a pointer to pointer and allocate the memory as in a ragged array, then use your existing swap
  • Declare matrix as an array of pointers and allocate memory for the rows, then use your existing swap
  • Keep the existing declaration of matrix and re-write the swap to swap every value.
  • Keep the existing declaration of matrix, but also provide an accessor array of pointers, use your existing swap on the accessor, and always use the accessor (the only possible advantage of this over the first two options is that everything resides on the stack).
  • Use the row-as-a-structure hack.

Row-as-a-structure

Consider this

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

m3 is an array of structures each of which is an array of ints. Access is a little awkword: m3[i].r[j], but you can do

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

to swap rows.

尝蛊 2024-12-13 09:57:10

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

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

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

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

C 语言的一个限制是数组的大小必须在编译时已知。

Arrays and pointers are different things, although C makes them behave similarly in many cases. You also accidentally used a char instead of an int for the second parameter. Your swapRows function should be declared like this:

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

You will need to swap (*a)[0] with (*b)[0] and (*a)[1] with (*b)[1].

C is converting the array into a pointer (with a warning), but that is confusing in this case.

It is just a limitation of C that arrays must have a size that is known at compile time.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文