【问题标题】:Swapping pointer in C [duplicate]在C中交换指针[重复]
【发布时间】:2016-06-01 03:50:05
【问题描述】:
# include <stdio.h>
void mystery (int *ptra, int *ptrb) {  
     int *temp; 
     temp = ptrb;  
     ptrb =ptra; 
     ptra = temp; 
} 
int main () { 
    int a = 2016, b=0, c= 4, d = 42; 
    mystery (&a, &b);
    if (a < c) 
          mystery (&c, &a); 
    mystery (&a, &d); 
    print f("%d\n", a); 
}

我的尝试:

a 和 d 不会交换,因为函数神秘()不会改变值,而是函数本地的指针。

请您正式解释一下。 mystery 的工作原理如何?

【问题讨论】:

  • 我正要回答。但“以正式方式”是什么意思?
  • 它不会直接对您的指针值做任何事情,它会暂时更改指针地址的副本,然后在函数返回时恢复值。
  • 编译器会推断该函数没有任何意义并完全优化掉它。
  • 此外,您不是在“查看”指针,而是打印a 的值。那么你期望你的函数会改变变量地址吗?
  • 这个“谜团”至少有 2 个重复项。

标签: c pointers parameter-passing


【解决方案1】:

在 C 中,函数总是按值传递。因此,您正在进行的指针交换在函数之外没有任何影响,因为您只是在更改本地值。

您需要交换它们指向的内容,而不是交换指针,即您需要取消引用它们:

void mystery (int *ptra, int *ptrb) {  
     const int temp = *ptrb;
     *ptrb = *ptra; 
     *ptra = temp; 
} 

【讨论】:

  • 是的。但是他在问他关于ab没有交换的原因是否正确。
  • 感谢您的精彩解释。
【解决方案2】:

您的临时需要是int 不是 int*

int temp = *ptrb;

那么你需要推迟指针:*ptrb = *ptra;

您当前所做的只是交换函数中的指针,这不会反映在函数调用者中。

【讨论】:

  • 感谢您的精彩解释。
  • 那么,为什么编译成功了?
  • 因为交换指针是完全合法的事情。
【解决方案3】:

a 和 d 没有交换,因为函数神秘()不会改变值,而是函数本地的指针。

是的,你是对的。函数mystery 不交换值。它只是将指针ptraptrb 分别交换到ptrbptra 指向的位置。

                        a
                 +--------------+
                 |              |
ptra ----------> |    2016      |
                 |              |
                 +--------------+



                        b
                 +--------------+
                 |              |
ptrb ----------> |      0       |
                 |              |
                 +--------------+

执行语句后

temp = ptrb;  
ptrb =ptra; 
ptra = temp;    

                        a
                 +--------------+
                 |              |
ptra -----+      |    2016      |
        +------> |              |
        | |      +--------------+
        | |
        | |
        | |
        | |             b
        | |      +--------------+
        | |      |              |
ptrb ---+ +----> |      0       |
                 |              |
                 +--------------+

【讨论】:

  • 感谢您的精彩解释。
  • 所以,这是一个有效的改变,rt?
  • 可以,但在这种情况下没有用。
  • 拜托,你能用英文解释第二张图吗?
  • 我已经解释过了。
【解决方案4】:

函数mystery() 几乎什么都不做,编译器通过优化消除了几乎所有的函数,只留下了ret

demo on Compiler Explorer

【讨论】:

  • 感谢您的精彩解释。
【解决方案5】:

首先要注意:传递给它的指针副本上的神秘炒锅。这有很大的影响,其中大多数是当您在 mystery 中分配指针 ptraptrb 时,您并没有更改原始指针。

void mystery (int *ptra, int *ptrb) {  
     int *temp; 
     temp = ptrb;  
     ptrb =ptra; 
     ptra = temp; 
}

第二件事:您确实将指针分配给指针,而不是指针指向的值。如果出现第一个错误,mystery 之外的世界根本看不到任何变化。

解决方案:

取消引用指针以更改它们指向的值。

void
mystery (int *ptra, int *ptrb)
{  
    const int tmp;

    tmp = *ptrb;
    *ptrb = *ptra; 
    *ptra = tmp; 
}

【讨论】:

  • 感谢您的精彩解释。
  • 那么,为什么编译成功了?
  • @RajUpadhyay 代码在语义上是正确的,只是它不是你想要的。