void swap(int * a,int * b)不使用数组

时间:2014-10-22 18:49:12

标签: c arrays pointers swap

C编程的新手,以及尝试创建一个交换两个变量值的void函数。当我希望交换两个整数变量的值时,以下函数可以正常工作,假设a = 11,b = 33,函数调用swap(& a,& b):

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

但是当我尝试使用数组的两个元素执行此操作时,它对交换(& a [0],& a [2])无法正常工作。但它确实可以使用以下功能:

void swap(int i, int j, int a[]) {
  int h = a[i];
  a[i] = a[j];
  a[j] = h;
}

有谁知道为什么第一个单变量的工作原理而不是数组元素?当然有一个非常好的解释,我在这里失踪。欢迎所有帮助,提前谢谢!!

这是完整的程序:

#include <stdio.h>
#include <stdlib.h>


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

void selectionSort(int a[], int len) {
  int i, j, min;
  for (i = 0; i < len; i++) {
    min = i;
    for (j = i+1; j < len; j++) {
      if (a[j] < a[min]) {
        min = j;
      }
    }
    swap(&a[i], &a[min]);
  }  
}

int main(int argc, char * argv[]) {
  int a[5] = {5, 4, 3, 2, 1};
  int len = 5, i;

  selectionSort(a, len);


  for (i = 0; i < len; i++) {
    printf("%d ", a[i]);
  }
  printf("\n");

    return 0;
}

数组值的输出为1 2 0 0。

4 个答案:

答案 0 :(得分:6)

让我猜一下 - 所有值都变为零?

如果a == b,您的交换功能会中断。尝试:

void swap(int *a, int *b) {
  if (a != b)
  {
      *a += *b;
      *b = *a - *b;
      *a -= *b; 
  }
}

答案 1 :(得分:1)

编写经典交换函数

总是更好
void swap( int *a, int *b )
{
   int tmp = *a;
   *a = *b;
   *b = tmp;;
}

或更改功能选择按以下方式排序

   void selectionSort(int a[], int len) {
      int i, j, min;
      for (i = 0; i < len; i++) {
        min = i;
        for (j = i+1; j < len; j++) {
          if (a[j] < a[min]) {
            min = j;
          }
        }
        if ( min != i ) swap(&a[i], &a[min]);
      }  
    }

答案 2 :(得分:0)

当两个参数指向同一个对象时,swap函数失败。我发现您在调用printf之前添加swap来电话就是这样做的,您可以自己尝试一下:

printf("swap(%d, %d)\n", i, min);
swap(&a[i], &a[min]);

您在swap函数中使用的算法:

*a += *b;
*b = *a - *b;
*a -= *b;

似乎是为了避免创建临时变量,但代价是(a)当两个对象相同时失败,以及(b)如果算术溢出则冒着未定义的行为的风险。 2&#s;补码整数的算术通常表现为环绕语义,我认为它会给你正确的结果,但它是一个不必要的复杂化。如果您正在处理浮点运算,那么它会遇到更多问题,其中运算会溢出或丢失精度。有一个类似的按位xor hack,它具有大多数相同的问题(并且根本没有浮点运算)。声明临时性将解决这两个问题:

const int old_a = *a;
*a = *b;
*b = old_a;

(将tmp这样的临时名称命名是常见的,但我想给它一个名称,以便更明确地告诉您它的用途;添加const告诉读者,在初始化之后它不会被改变。)

但这不是唯一的问题。您尝试与自己交换数组元素的事实表明您的selectionSort函数也有错误;正确的排序算法永远不会将元素与自身交换,因为它没有用处。

如果你修复selectionSort,你可能不需要来修复swap,但我建议你这样做。

答案 3 :(得分:-4)

如果是数组元素,只需使用[0]和[2],不要使用&#34;&amp;&#34;运算符作为数组是自己的指针,因此您不需要提供任何引用。