【问题标题】:C: swapping pointers in an arrayC:交换数组中的指针
【发布时间】:2023-11-27 09:25:01
【问题描述】:

我有一个包含指针的数组。如何正确交换两个指针 - 比如说 array[1] 和 array[4]?

【问题讨论】:

  • 既然我看到了你关于数组的其他问题,我需要问:那些是函数指针吗?如果是,则无法保证使用 void * 的解决方案有效。
  • 我在一个包含如下指针的 int 数组上执行交换:myPointerArray[0] 指向 array[0],myPointerArray[1] 指向 array[1] 等等。这会导致问题吗?
  • 唯一的问题是如果你混合指向数据的指针和指向函数的指针。在某些架构上,数据和功能必须分开寻址空间,您不能这样做:int f(); void *p; ... p = f;。如果我明白你所说的,你应该没问题,但你可能会发布更多代码来确定。

标签: c pointers


【解决方案1】:

你需要一个临时变量:

void*temp = array[4];
array[4]=array[1];
array[1] = temp;

编辑固定的第一行。

【讨论】:

  • 第 1 行应该是数组[4],不是吗?
  • 你的代码错了,只是数组索引的混淆。它将 array[1] 复制到 temp,然后覆盖 array[4] 并将 temp 放回 array[1]。
  • Void 只是一个指针,并没有实际指定数据类型。
  • 在您的代码中,无论数组的类型是什么。如果你有 int* array[N],其中 N 是某个大小,或者 int** 数组,其中 array 指向保存在其他地方的数组,它将是 int*。
  • @Pieter,类型为void *,即指向void的指针。 C 标准保证任何对象指针都可以转换为 void * 并返回——因此,上述内容与 array 中的指针类型无关。
【解决方案2】:
void* temp = array[1]; 
array[1] = array[4]; 
array[4] = temp;

【讨论】:

    【解决方案3】:

    最正确的方法是使用临时变量,如下所示:

    void *tmp_pointer;
    
    ....
    tmp_pointer = array[1];
    array[1] = array[4];
    array[4] = tmp_pointer;
    ....
    

    远离任何邪恶的位或 int hacks! :)

    让我在这里补充一下,我们应该问“什么类型的指针?

    理论上,您不能安全地混合指向数据的指针和指向函数的指针。 C 标准不保证这将是有意义的或可能的。它只确保:

    • 数据指针可以从void *转换回来
    • ((void *)0) 是一个不同于任何数据指针或函数指针的指针
    • 一种类型的函数指针可以转换为另一种类型的函数指针并返回。

    我知道这是因为在某些架构中,数据的地址空间与函数的地址空间完全分离,您无法安全地从一个类型的指针转​​换到另一个类型的指针并返回。

    【讨论】:

    • 哦,但这意味着没有异或交换...:P
    • 我想有人会这么建议。如果他们还没有,有人会的!太邪恶了:)
    【解决方案4】:
    #include <stdint.h>
    if (1 != 4) {
        array[1] = (void*)((intptr_t)(array[1]) ^ (intptr_t)(array[4]));
        array[4] = (void*)((intptr_t)(array[1]) ^ (intptr_t)(array[4]));
        array[1] = (void*)((intptr_t)(array[1]) ^ (intptr_t)(array[4]));
    }
    

    更清晰,节省了一个临时的。 ;-)

    【讨论】:

    • 虽然你需要检查 1 != 4 否则你会泄漏内存,通过空指针。
    • 很想给你 -1 表示“更清晰”,这显然是错误的。但答案有效,所以我不会反对。 :-)
    • 我知道!邪恶无处不在:)
    • @Graeme,我怀疑这很讽刺。看到笑容了吗?
    • @JP:支票真的需要吗?如果两者相等,那么这三个步骤将是:array[1] = 0;数组[4] = 数组[4]; array[1] = array[4],这将使一切正常......还是我错过了什么?
    【解决方案5】:

    我的 C 很生锈,但是很简单

    int* foo = array[4];
    array[4] = array[1];
    array[1] = foo;
    

    应该够了。

    【讨论】: