Void swap (int * a, int * b) doesn't work with array

New to C programming and trying to make a void function that changes the values ​​of two variables. When I want to swap the values ​​of two integer variables, the following functions work just fine, so let's say a = 11, b = 33 with function call replacement (& a, & b):

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

      

But when I try to do it with two array elements, it doesn't work correctly for swap (eg [0], & a [2]). However, it works with the following function:

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

      

Does anyone know why the first individual variables work, but not with array elements? Of course there is a very good explanation that I am missing here. All help is appreciated, thanks in advance!

Here's the complete program:

#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;
}

      

The output for array values ​​is 1 2 0 0.

+3


source to share


4 answers


Let me guess - do all values ​​vanish?

The swap function is aborted if a == b

. Try:



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

      

+6


source


It's always better to write a classic swap function

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

      



Or select change function Create the following path

   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]);
      }  
    }

      

+1


source


The function swap

does not work when both arguments point to the same object. I found out that you were doing this by adding a call printf

before the call swap

, that you could try it yourself:

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

      

The algorithm that you used in your function swap

:

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

      

does not seem to allow creating a temporary variable, but at the cost of (a) failure when both objects are the same, and (b) risking undefined behavior if there is arithmetic overflow. Integer arithmetic with 2 words will usually behave using semantics that (I think) will give you correct results, but this is an unnecessary complication. It has even more problems if you are dealing with floating point, where arithmetic can overflow or lose precision. There's a similar bitwise xor hack that has most of the same problems (and it doesn't work with floating point at all). A workaround announcement will address both issues:

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

      

(Usually called temporary something like tmp

, but I like to give it a name that tells you more clearly what it is used for; the addition const

tells the reader that it will not be changed after you initialize it.)

But this is not the only problem. The fact that you are trying to swap the array elements on their own indicates that your function selectionSort

will not work either; the correct sorting algorithm will never swap an element for itself, because it is useless for that.

If you fix selectionSort

, you probably don't need to fix swap

, but I recommend doing it anyway.

0


source


For array elements, use only [0] and [2] and do not use "&". operator, since arrays are pointers themselves, so you don't need to give any references.

-4


source







All Articles