Is there any built in swap function in C which works without using a third variable?
No.
C++ builtin swap function: swap(first,second);
Check this: http://www.cplusplus.com/reference/algorithm/swap/
You can use this to swap two variable value without using third variable:
a=a^b;
b=a^b;
a=b^a;
You can also check this:
https://stackoverflow.com/questions/756750/swap-the-values-of-two-variables-without-using-third-variable
How to swap without a third variable?
Why do you not want to use a third variable? It's the fastest way on the vast majority of architectures.
The XOR swap algorithm works without a third variable, but it is problematic in two ways:
The variables must be distinct i.e. swap(&a, &a) will not work.
It is slower in general.
It may sometimes be preferable to use the XOR swap if using a third variable would cause the stack to spill, but generally you aren't in such a position to make that call.
To answer your question directly, no there is no swap function in standard C, although it would be trivial to write.
Assuming you want a C solotion, not a C++ one, you could make it a macro, at least using GCC extension to have it generic enough, something like
#define SWAP(x,y) do { \
typeof(x) _x = x; \
typeof(y) _y = y; \
x = _y; \
y = _x; \
} while(0)
beware of tricks like invocations swap(t[i++],i); to avoid them, use the address operator &. And you'll better use a temporary (for integers, there is a famous and useless trick with exclusive-or).
PS: I'm using two local variables _x and _y (but I could have used one local variable only) for better readability, and perhaps also to enable more optimizations from the compiler.
There is no such function in standard C.
(In C++ you have std::swap().)
Maybe a macro from this question can be useful for you.
There is no standard function in C to swap two variables.
A macro can be written this way:
#define SWAP(T, a, b) do { T tmp = a; a = b; b = tmp; } while (0)
and the macro can be called this way:
int a = 42;
int b = 2718;
SWAP(int, a, b);
Some solutions for a writing a SWAP macro should be avoided:
#define SWAP(a, b) do { a = b + a; b = a - b; a = a - b; } while (0)
when operands are of signed types an overflow can occur and signed overflow are undefined behavior.
Also a solution trying to optimize the XOR solution like this should be avoid:
#define SWAP(a, b) (a ^= b ^= a ^=b)
a is modified twice between the previous and the next sequence point, so it violates the sequence points rules and is undefined behavior.
Since you may copy any object representation into an unsigned char array in C, the following macro allows you to swap any two objects:
#define SWAP(X,Y) \
do { \
unsigned char _buf[sizeof(*(X))]; \
memmove(_buf, (X), sizeof(_buf)); \
memmove((X), (Y), sizeof(_buf)); \
memmove((Y), _buf, sizeof(_buf)); \
} while (0)
GCC will even generate optimal code for this in some cases. You might not keep your job though...
There is is a C++ library function. It swaps the values of two integer variables. For example, swap(x, y); will swap the values of variables x and y. Similarly, swap(mat[i][j], mat[j][i]); will swap two values in matrix mat, namely the value in row i column j and the value in row j column i.
#define swap(T, x, y) \
{ \
T tmp = x; \
x = y; \
y = tmp; \
}
int main()
{
int a = 10;
int b = 20;
printf("a=%d b=%d\n", a, b);
swap(int, a, b);
printf("a=%d b=%d\n", a, b);
return 0;
}
There is no built-in swap function but you can try this
a = a ^ b;
b = a ^ b;
a = b ^ a;
I believe I've come up with a type-agnostic function for swapping any two values in standard C, though since I'm fairly new to the language I may have overlooked something. It uses the XOR swap algorithm, and I'm sure it could be optimized more, but it works as long as the two values point to the same number of bytes, specified by the 3rd argument:
void swapn(void *a, void *b, size_t n) {
if (a == b) {
return;
}
size_t i;
char *x = (char *)a,
*y = (char *)b;
for (i = 0; i < n; i++) {
*x ^= *y;
*y ^= *x;
*x ^= *y;
x++;
y++;
}
}
Example usage:
// swap two integers
int x = 5,
y = 30;
printf("%d\t%d\n", x, y);
swapn(&x, &y, sizeof(int));
printf("%d\t%d\n\n", x, y);
// swap two floats
float a = 9.23f,
b = 6.83f;
printf("%.2f\t%.2f\n", a, b);
swapn(&a, &b, sizeof(float));
printf("%.2f\t%.2f\n\n", a, b);
// swap two doubles
double p = 4.7539,
q = 0.9841;
printf("%.4f\t%.4f\n", p, q);
swapn(&p, &q, sizeof(double));
printf("%.4f\t%.4f\n\n", p, q);
// swap two chars
char m = 'M',
n = 'n';
printf("%c\t%c\n", m, n);
swapn(&m, &n, sizeof(char));
printf("%c\t%c\n\n", m, n);
// swap two strings of equivalent length
char s[] = "Hello",
t[] = "World";
printf("%s\t%s\n", s, t);
swapn(s, t, sizeof(s));
printf("%s\t%s\n\n", s, t);
The output is:
5 30
30 5
9.23 6.83
6.83 9.23
4.7539 0.9841
0.9841 4.7539
M n
n M
Hello World
World Hello
Related
Why my code output is 5 and 0, not 6 and 5?
I think I should get 6 and 5. I am a beginner.
#include <stdio.h>
int swap(int a,int b);
int main()
{ int x =5;
int y =6;
printf("%d %d\n",x,y);
int number[2]={swap(x,y)};
x=number[0];
y=number[1];
printf("%d %d\n",x,y);
return 0;
}
int swap(int a,int b)
{
return b,a;
}
There are several things wrong here.
First, you can't return multiple values in C, like you can in Python. return b, a; uses the comma operator, which evaluates both its operands and returns the second one. So this is equivalent to just return a;.
Second, your array initializer is only initializing the first element of the array. There's only one expression in the initialization braces, so that initializes number[0]. The remaining elements of the array are initialized by default to 0.
Combining both of these, it's equivalent to:
int number[2] = {y, 0};
I can see you are new to C programming. The problem is in your swap() function. You're using a language construct that does not exist in C, namely tuples. Check out pointers for a proper way to return multiple values from a function.
This function ...
int swap(int a,int b)
... returns one int, as its prototype says.
This statement ...
return b,a;
... involves C's comma operator ,, which evaluates its left-hand operand, discards the result, then evaluates to the value of its right-hand operand. Since evaluating b has no side effects in your case, that return statement is equivalent to
return a;
In C, it is valid to initialize an array with fewer explicit elements than the length of the array. For an automatic (local, non-static) array such as yours, as long as at least one element is initializer, all elements not explicitly initialized are implicitly initialized (to 0 in the case of int elements). Thus, for your implementation of swap(), this ...
int number[2]={swap(x,y)};
... is equivalent to
int number[2] = { x, 0 };
, which explains the output.
Here is a way to solve your problem.
#include <stdio.h>
void swap(int *a,int *b);
int main()
{
int x = 5;
int y = 6;
swap(&x, &y);
printf("post swap x = %d, y = %d\n", x, y);
return 0;
}
// No need to return anything, we change the x, y values using the pointer
// This is passing by reference. Instead of passing the value, we are
// passing the reference (i.e address of the variable). swap function can
// now directly access the values and change them
void swap(int *a, int *b)
{
int tmp;
printf("Swap got a = %d, b = %d\n", *a, *b); // Note: we access value of a pointer using * in front of the pointer varaible
tmp = *a;
*a = *b;
*b = tmp;
}
outputs:
bhakta: /tmp$ cc x.c
bhakta: /tmp$ ./a.out
Swap got a = 5, b = 6
post swap x = 6, y = 5
This might be a very stupid question but i don't understand this:
If i have:
void* a;
void* b;
And I want to implement a generic swap function, why can't I do this:
void swap(void* a, void* b)
{
void* temp = malloc(sizeof(*a));
*a = *b;
*b = *temp;
free(temp);
}
Thank you
I added this later on:
So i understand now why it is impossible but now i have another question:
Since
sizeof(*a)
is undefined, someone told me i could do this:
#define SWAP(a,b) \
{ \
void* temp = malloc(sizeof(*a)); \
memcpy(temp , a , sizeof(*a)); \
memcpy(a, b, sizeof(*a)); \
memcpy(b, temp, sizeof(*a));
free(temp);
}
of course i assume a and b are of the same type.
Why will this solution work?
thank you
You cannot dereference a void *, there is no information about the type of data it's pointing at. So your code won't compile, which is why you cannot do that.
That's the point of void *, it's a "pointer to anything", and there is absolutely no additional information available if you don't add it yourself.
If I have:
char a; /* size 1 */
int b; /* assume size 4 */
and call:
swap(&a, &b); /* assuming it compiled */
All information the function gets is the address of the two variables. There's no way for the function (or the compiler) to magically follow those pointers backward and figure out what the sizes of the pointed-to values are. None.
This way you only "copy" the pointer address but not the actual data. once after you freed temp, y becomes an invalid address. Besides that you're not using a or b in any case
To answer your 2nd question, your SWAP() macro will still NOT work as intended if you pass void* pointers to it. Or for that matter, if you pass two pointers of different types.
It will work for something like this:
int a = 2, b = 3;
char c = '0', d = '1';
SWAP(&a, &b);
SWAP(&c, &d);
This question already has answers here:
Implement generic swap macro in C [duplicate]
(6 answers)
Closed 9 years ago.
Is there any logic in c which can swap any type of two variables. i.e int, float, sequence of character.
I can think of a logic of storing every type of variables as sequence of characte and swap it like normal string but i does not its good idea.
Let's see how you'd do this for two char variables. You'd do something like this.
void swap(char* a, char* b)
{
char tmp = *a;
*a = *b;
*b = tmp;
}
For two int variables:
void swap(int* a, int* b)
{
int tmp = *a;
*a = *b;
*b = tmp;
}
And so on. Now, for catering to any type of variable, you'd be tempted to do:
void swap(void* a, void* b)
{
// ...
}
But you'd need to allocate a space of a parameterized size. So, you'll have to first receive that size as a parameter:
void swap(void* a, void* b, size_t s)
{
// ...
}
...which you'll pass as an argument using a sizeof expression. And you'll need to allocate said space and do assignments (copies) using that. Off the top of my head, malloc/free and memcpy come to mind, so a crude way to do what we did above for char and int, but this time with a parameterized size, would be:
void swap_any(void* a, void* b, size_t s){
void* tmp = malloc(s);
memcpy(tmp, a, s);
memcpy(a, b, s);
memcpy(b, tmp, s);
free(tmp);
}
As I described, this is a little crude. You could try doing it with alloca (which allocates on the stack) and no free.
Alternatively, you could do it with a macro, since you can pass a type (instead of a size_t) to a macro - because macros essentially work using text replacement. Then, you can obviously create the temporary variable type by name, like this:
#define swap_m(a, b, t) { t tmp = a; a = b; b = tmp; }
Obviously, if you don't want to pass any information at all about the involved types, you'd have to be more creative about it.
You can use a macro for that, but it won't work for everything:
#define SWAP(a,b) { __typeof__(a) temp; temp = a; a = b; b = temp; }
I have this:
unsigned int y = (unsigned int)(int*)foo;
How do I get the address to where is stored in memory value which foo points?
Let's try to explain better, assume that thery are of int type:
int x = 10;
int *foo = &x;
unsigned int y = (unsigned int)(int*)foo;
int r = MAGIC(y); /* should be 10 */
x = 13; /* r still should be 10 */
y should hold x's adddress, it is, address of 10 integer.
r should copy the value at y location, it is, 10 integer.
so any change of x (as in x = 13) shouldn't change value r. This just an int.
The question is: How do I define MAGIC?
If what you want is possible, then
#define MAGIC(y) (*((int*)(y)))
will do it.
Your code is trying to use y as a pointer when in fact it is defined to the C-compiler as an unsigned integer. Code that was written back in the "bad ol' days" would do stuff like your example.
Code should be more explicit and well defined in its intent, thus:
#include <stdlib.h>
main()
{
int x = 10;
int *foo = &x;
int *y = foo;
#define MAGIC(A) *A
int r = MAGIC(y); /* should be 10 */
x = 13; /* r still should be 10 */
printf("x=%d, r=%d", x, r);
// printed (as expected) :: x=13, r=10
}
These days there is NO reason to work around a C-compiler!!
If you are maintaining some old code that does stuff like your original example, then it is probably worth the effort to re-write it using today's programming style. Note, it can remain written in C, just well-formed C!
If y is to hold the address of x then it should be declared as:
unsigned int *y;
MAGIC should simply be the what is pointed to by operator.
int r = *y;
MAGIC is just the asterisk.
Is there any built in swap function in C which works without using a third variable?
No.
C++ builtin swap function: swap(first,second);
Check this: http://www.cplusplus.com/reference/algorithm/swap/
You can use this to swap two variable value without using third variable:
a=a^b;
b=a^b;
a=b^a;
You can also check this:
https://stackoverflow.com/questions/756750/swap-the-values-of-two-variables-without-using-third-variable
How to swap without a third variable?
Why do you not want to use a third variable? It's the fastest way on the vast majority of architectures.
The XOR swap algorithm works without a third variable, but it is problematic in two ways:
The variables must be distinct i.e. swap(&a, &a) will not work.
It is slower in general.
It may sometimes be preferable to use the XOR swap if using a third variable would cause the stack to spill, but generally you aren't in such a position to make that call.
To answer your question directly, no there is no swap function in standard C, although it would be trivial to write.
Assuming you want a C solotion, not a C++ one, you could make it a macro, at least using GCC extension to have it generic enough, something like
#define SWAP(x,y) do { \
typeof(x) _x = x; \
typeof(y) _y = y; \
x = _y; \
y = _x; \
} while(0)
beware of tricks like invocations swap(t[i++],i); to avoid them, use the address operator &. And you'll better use a temporary (for integers, there is a famous and useless trick with exclusive-or).
PS: I'm using two local variables _x and _y (but I could have used one local variable only) for better readability, and perhaps also to enable more optimizations from the compiler.
There is no such function in standard C.
(In C++ you have std::swap().)
Maybe a macro from this question can be useful for you.
There is no standard function in C to swap two variables.
A macro can be written this way:
#define SWAP(T, a, b) do { T tmp = a; a = b; b = tmp; } while (0)
and the macro can be called this way:
int a = 42;
int b = 2718;
SWAP(int, a, b);
Some solutions for a writing a SWAP macro should be avoided:
#define SWAP(a, b) do { a = b + a; b = a - b; a = a - b; } while (0)
when operands are of signed types an overflow can occur and signed overflow are undefined behavior.
Also a solution trying to optimize the XOR solution like this should be avoid:
#define SWAP(a, b) (a ^= b ^= a ^=b)
a is modified twice between the previous and the next sequence point, so it violates the sequence points rules and is undefined behavior.
Since you may copy any object representation into an unsigned char array in C, the following macro allows you to swap any two objects:
#define SWAP(X,Y) \
do { \
unsigned char _buf[sizeof(*(X))]; \
memmove(_buf, (X), sizeof(_buf)); \
memmove((X), (Y), sizeof(_buf)); \
memmove((Y), _buf, sizeof(_buf)); \
} while (0)
GCC will even generate optimal code for this in some cases. You might not keep your job though...
There is is a C++ library function. It swaps the values of two integer variables. For example, swap(x, y); will swap the values of variables x and y. Similarly, swap(mat[i][j], mat[j][i]); will swap two values in matrix mat, namely the value in row i column j and the value in row j column i.
#define swap(T, x, y) \
{ \
T tmp = x; \
x = y; \
y = tmp; \
}
int main()
{
int a = 10;
int b = 20;
printf("a=%d b=%d\n", a, b);
swap(int, a, b);
printf("a=%d b=%d\n", a, b);
return 0;
}
There is no built-in swap function but you can try this
a = a ^ b;
b = a ^ b;
a = b ^ a;
I believe I've come up with a type-agnostic function for swapping any two values in standard C, though since I'm fairly new to the language I may have overlooked something. It uses the XOR swap algorithm, and I'm sure it could be optimized more, but it works as long as the two values point to the same number of bytes, specified by the 3rd argument:
void swapn(void *a, void *b, size_t n) {
if (a == b) {
return;
}
size_t i;
char *x = (char *)a,
*y = (char *)b;
for (i = 0; i < n; i++) {
*x ^= *y;
*y ^= *x;
*x ^= *y;
x++;
y++;
}
}
Example usage:
// swap two integers
int x = 5,
y = 30;
printf("%d\t%d\n", x, y);
swapn(&x, &y, sizeof(int));
printf("%d\t%d\n\n", x, y);
// swap two floats
float a = 9.23f,
b = 6.83f;
printf("%.2f\t%.2f\n", a, b);
swapn(&a, &b, sizeof(float));
printf("%.2f\t%.2f\n\n", a, b);
// swap two doubles
double p = 4.7539,
q = 0.9841;
printf("%.4f\t%.4f\n", p, q);
swapn(&p, &q, sizeof(double));
printf("%.4f\t%.4f\n\n", p, q);
// swap two chars
char m = 'M',
n = 'n';
printf("%c\t%c\n", m, n);
swapn(&m, &n, sizeof(char));
printf("%c\t%c\n\n", m, n);
// swap two strings of equivalent length
char s[] = "Hello",
t[] = "World";
printf("%s\t%s\n", s, t);
swapn(s, t, sizeof(s));
printf("%s\t%s\n\n", s, t);
The output is:
5 30
30 5
9.23 6.83
6.83 9.23
4.7539 0.9841
0.9841 4.7539
M n
n M
Hello World
World Hello