【问题标题】:Swapping Pointers to pointers in C将指针交换到 C 中的指针
【发布时间】:2012-04-02 04:59:22
【问题描述】:

我有一个问题,涉及调用一个带有指向指针的指针的 2 个参数的函数

int main(void)
{ ...
int *ptrp = &p, *ptrq = &q;
int **ppp = &ptrp, **ppq  = &ptrq;
swap_ptr(ppp,ppq);/* &ptrp, &ptrq passed */ 
/* to swap_ptr() */
return 0;
}

void swap_ptr(int **ptrA,int **ptrB)...

我们必须交换 ptrp 和 ptrq 的值,那么这是否意味着在 swap_ptr 函数中我只是使用 *ptrA 和 *ptrB 来交换它们,还是其他一些指针语句?

谢谢

【问题讨论】:

  • 你的问题有答案,所以我不太确定为什么需要问它......
  • 您也可以使用XOR swap 来交换指针...
  • @0x69 有趣的事实:如果异或交换两个相同的指针,那么它们都将被设置为 NULL 指针。
  • @Corbin 这取决于您的意思是“相同的指针”。如果它意味着相同的指针变量 - 那么是的,你不能交换相同的 var - XOR交换必须应用于存储在不同内存地址的两个变量。但是,如果说“相同的指针”是指指向相同地址的不同指针变量 - 那么不,您可以完美地交换这两个指针。例如 - 下面的代码在 XOR 交换适用性方面 100% 有效 =>
  • void xorSwap (int **x, int **y) { if (x != y) { *x = (int*)((int)*x ^ (int)*y); *y = (int*)((int)*x ^ (int)*y); *x = (int*)((int)*x ^ (int)*y); } } int main(void){ int a = 7; int b = 11; int * pa = &b; int * pb = &b; printf("before %p %p / %d %d\n", pa, pb, *pa, *pb); xorSwap(&pa, &pb); printf("after %p %p / %d %d\n", pa, pb, *pa, *pb); return 0; }

标签: c function pointers swap


【解决方案1】:

这与交换任何东西的概念相同:

void swap(int* a, int* b)
{
    int tmp = *a;
    *a = *b;
    *b = tmp;
}

在这种情况下,你只是碰巧在交换 int* 而不是 int:

void swap(int** a, int** b)
{
    int* tmp = *a;
    *a = *b;
    *b = tmp;
}

【讨论】:

    【解决方案2】:

    是的,*ptrA 将引用main 中的变量ptrp,而*ptrA 将引用ptrq。像对任何其他类型一样交换这两个值,ptrp 现在将指向 qptrq 指向 p

    既然这听起来像是家庭作业,我会让你想出三行代码。

    【讨论】:

    • 非常感谢,这就是我需要知道的全部内容
    【解决方案3】:

    *ptrp 指的是指针所指向的值。 ptrp 指的是指针的值(内存位置)

    swap_ptr 可以简单地将其中一个值存储在 tmp var 中,然后交换这些值。

    【讨论】:

      【解决方案4】:

      我对这些算法/技术有点陌生,但我想出了这个功能;

      function swap(int *p1, int *p2) {
        *p1 = *p1 + *p2;
        *p2 = *p1 - *p2;
        *p1 = *p1 - *p2;
      }
      

      你可以这样测试这个函数;

      int a = 10;
      int b = 20;
      
      printf("%d %d\n", a, b); // 10 20
      
      swap(&a, &b);
      
      printf("%d %d\n", a, b); // 20 10
      

      为了更好地理解,这里有一个 3 步解释;

      1. *p1 = *p1 + *p2;
        添加来自 p1 (*p1=10)p2 (*p2=20) 的值并存储p1 (*p1=30) 上的结果。
      2. *p2 = *p1 - *p2;
        我们知道加法的结果,通过从传入的值中减去 p2 (current *p2=20) 的当前值来计算 p1 的旧值从 p1 (*p1=30) 并将结果存储在 p2 (计算 *p2=10)
      3. *p1 = *p1 - *p2;
        由于 p1 (*p1=30) 的值在第 2 步没有改变,我们仍然在 p1 的旧值>p2 (*p2=10),我们可以将p2分成p1,并将结果存储在p1 (计算 *p1=20)

      如您所见,我们交换了两个ints 没有定义任何临时变量并进行传递引用函数调用。

      传递引用的原因是为了尽量减少内存的使用。因为每次传值调用都会在内存中分配新变量(是否被 GC 删除)取决于您传递给函数的参数量。

      【讨论】:

      • -1 这是一种非常危险的值交换方式,如*.com/questions/20753278/…中所述
      • @JoeHass 为什么它很危险?正如您在更新 1 中看到的,最大值 int 没有任何问题。什么原因导致swap()函数出现危险情况?
      • 您证明它会一次工作,这与证明它会总是工作有很大不同。您是否检查过 C 语言标准对有符号整数溢出时的情况有何规定?
      最近更新 更多