【问题标题】:Swapping two variable using pointers使用指针交换两个变量
【发布时间】:2012-12-20 15:40:21
【问题描述】:

我正在尝试使用指针(特别是 void 指针)按引用编写交换函数,但我的代码无法正常工作。这是我的代码:

void swap(void *p1,void *p2) 
{
    int temp;   
    temp=*((int*)p2);
    p2=p1; 
    p1=&temp;
}

int main() 
{
    int i=4;
    int j=5; 
    cout<<i<<j<<endl;
    swap(&i,&j); 
    cout<<i<<j<<endl;
    return 0;
}

我哪里错了?

【问题讨论】:

  • 这在很多方面都被破坏了,但最重要的问题 (IMO) 是为 p1,p2 分配值,而您实际上需要分配它们的地址。这不是唯一的问题,只是最重要的 IMO。
  • 是否需要通过引用传递指针?
  • 因为你在交换整数,你不需要将函数参数作为空值传递。

标签: c++ void-pointers


【解决方案1】:

代码不起作用,因为您没有取消对分配的指针的引用。应该是

*((int*)p2)=*((int*)p1);
*((int*)p1)=temp;

请注意,您假设void* 指向int,但显然并非总是如此。从本质上讲,您不妨将void* 替换为int*,然后去掉演员表。

更一般的 API 案例应如下所示:

void swap(void *p1,void *p2, size_t sz)

在内部,API 应该分配一个大小为sz 的缓冲区,在其中创建一个memcpy,然后进行交换,再次使用memcpy

【讨论】:

  • 这是假设类型可以简单地复制-。
  • @R.MartinhoFernandes 对——本质上,这相当于在非重叠区域中进行内存内容的微不足道的交换。
【解决方案2】:

在函数体中,您交换了p1p2 的值;你不想那样做。您想交换 p1p2 指向的值:

void swap(int *p1, int *p2)
{
  int tmp = *p1;
  *p1 = *p2;
  *p2 = tmp;
}

我知道你想使用void * 来表达你的论点。不。无论如何,您都必须将它们转换为适当的目标类型才能执行分配:

int tmp = *(int *) p1;
*(int *) p1 = *(int *) p2;
*(int *) p2 = tmp;

哎呀。通过提出void * 的论点,您并没有为自己节省任何东西。

由于您显然是在编写 C++,因此您可以使用模板使函数泛型:

template<typename T>
void swap(T *p1, T *p2)
{
  T tmp = *p1;
  *p1 = *p2;
  *p2 = tmp;
}

更好的是,使用模板和引用,这样你根本不用处理指针:

template<typename T>
void swap(T &p1, T &p2)
{
  T tmp = p1;
  p1 = p2;
  p2 = tmp;
}

【讨论】:

  • 等一下 - 我没有在某处看到最后一个函数吗?
【解决方案3】:

使用记忆功能

void swap (void *vp1, void *vp2, const int size) {
char *buffer = (char *)malloc(sizeof(char)*size);
memcpy(buffer, vp1, size);
memcpy(vp1, vp2, size);
memcpy(vp2, buffer, size);
free(buffer);
}

int main()
{
int a = 10, b = 20;
printf("%d %d"a,b);
swap(&a, &b, sizeof(int));
printf("%d %d"a,b);

}

Output is:

10 , 20
20 , 10

如果我们不知道数据类型,那么我们使用 void。

【讨论】:

  • 实际上,在 C++ 中,当我们还不知道类型时,我们使用template &lt;typename T&gt;。编译器会知道,使用真正的类型T,然后检查错误。这就是为什么我们有template &lt;typename T&gt; std::swap(T&amp;, T&amp;)
【解决方案4】:

您正在修改指针的副本,而不是它们的内容。 你应该做这样的事情(只是向你展示这个想法,如果没有演员表,这将无法工作,而且它仍然不是一个好主意):

temp = *p2
*p2 = *p1;
*p1 = temp;

如果你想交换你的指针,你将需要指向指针的指针:

void swap(void** ptr1, void** ptr2);

或对指针的引用:

void swap(void*& ptr1, void*& ptr2);

或者由于您显然使用的是 C++,您可以使用引用和模板来交换任何类型的数据。但是您确定您了解该语言的所有基础知识吗?

祝你好运

【讨论】:

    【解决方案5】:

    试试这个:

    #include <iostream>
    using namespace std;
    
    void swap( void *a, void *b ) {
      int tmp = *( ( int* )a );
      *( ( int* )a ) = *( ( int* )b );
      *( ( int* )b ) = tmp;
    }
    
    int main() {
      int a, b;
      cin >> a >> b;
      swap( &a, &b );
      cout << a << " " << b;
      return 0;
    }
    

    在取消引用指针 a 和 b 之前,必须先将它们转换为 int*。之后,您只需执行交换即可。

    注意:您不需要将void* 作为参数传递。如果你通过int*s,它也是正确的(并且更具可读性)。

    注意[2]:由于您使用 C++ 编程,您可以使用指针引用来代替。

    【讨论】:

      【解决方案6】:

      试试下面的代码:

      #include <iostream>
      using namespace std;
      
      void Swap(int **ptr1, int **ptr2){
          // Swapping the contents of p1 and p2 in the driver function
          int *temp;
          temp = *ptr1;                   
          *ptr1 = *ptr2;
          *ptr2 = temp;
          // Swapping the contents of x and y in the driver function
          int temp;
          temp = **ptr1;                  
          **ptr1 = **ptr2;
          **ptr2 = temp;
      }
      
      int main(){
          int x = 10, y = 15;
          int *p1 = nullptr;
          p1 = &x;
          int *p2 = nullptr;
          p2 = &y;
          cout << x << ' ' << y << endl;
          cout << *p1 << ' ' << *p2 << endl;
          Swap(&p1,&p2);
          cout << x << ' ' << y << endl;
          cout << *p1 << ' ' << *p2 << endl;
      }
      

      【讨论】:

        【解决方案7】:

        在驱动函数中交换p1和p2的内容 代码不起作用。这可能是因为您试图交换内存地址起始位置,而操作系统对此进行了限制。 ?? 然而,记忆功能可以完成这项工作。

        【讨论】:

        • 这对 OP 几乎没有帮助。你能举例说明“记忆功能”是如何工作的吗?
        猜你喜欢
        • 1970-01-01
        • 2013-03-07
        • 2014-06-04
        • 1970-01-01
        • 2012-06-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多