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.
source to share
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]);
}
}
source to share
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.
source to share