MMGames Introduction to C C Language Development Environment C language now Useful Apps Contact Us
MMGames

Automatic version identification

SpineViewer

It's easy to tell by looking at it.

Response Time Checker

I can leave my computer on and do it.

Mouse cleaning time

I can leave my computer on and do it.

Mouse cleaning time

C language learned by suffering
C language learned by suffering

SWAP macro

SWAP macro
SWAP is a macro or function that exchanges the values of two variables.
This function itself is very simple, but on the contrary, it is therefore
Many people wonder if it is possible to achieve this using only macros, and it has become quite a topic of discussion.

First, let's start with the most basic function implementation.
Since we need to change the value of two variables, we naturally use pointer type arguments.
All that's left to do is to swap the two variables on the function's side, but here's the catch.

source code
 void swap(int* a, int* b)
{
    *a = *b;
    *b = *a;
    return;
}

This means that it is not possible to use the method of
Because once you assign *b to *a, the contents of *a are the same as the contents of *b, so
Substituting *a for *b after that is meaningless.

Therefore, it is necessary to declare another local variable and save *a there.
The following program is an example of the most standard implementation of the swap function.

source code
 #include <stdio.h>

void swap(int* a, int* b);

int main(void)
{
    int a = 10, b = 100;
    printf("a = %3d : b = %3d\n", a, b);
    swap(&a, &b);
    printf("a = %3d : b = %3d\n", a, b);
    return 0;
}

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

The results of running this program are as follows

Execution Result
a = 10 : b = 100
a = 100 : b = 10

All that remains is to prepare this for each type.
Since features like inlining, overloading, and templates are not available in C
Each type must be named separately and created one by one.
That's hard to use, and even in C++, I'd be concerned about the overhead of calling
It seems that there are quite a few people who would like to somehow achieve this using only macros.

The first thought was to implement by addition and subtraction as follows.

Source code
 #define SWAP(a, b) (a += b, b = a - b, a -= b)

The principle is simple. Add b first, and then store the value of b.
At first glance, overflow due to addition is a concern.
Even if it overflows, the added amount is looped over, so it works without any problem.

Another method using exclusive disjunction was also conceived.

Source code
 #define SWAP(a, b) (a ^= b, b = a ^ b, a ^= b)

I won't go into the details of exclusive disjunction, but in principle there is not much difference.
In general, exclusive or is slightly faster than addition or subtraction, so it is used in some cases.
However, it cannot be used for real values, making it less versatile.

These two macros work fine for the most part, but
In fact, there are cases where it does not work well, and that is the biggest problem.
It happens when the same variable is specified.
Since this is more proof than argument, we will actually try it out.

Source Code
 #include <stdio.h>

#define SWAP(a, b) (a += b, b = a - b, a -= b)

int main(void)
{
    int a = 98;
    printf("a = %3d\n", a);
    SWAP(a, a);
    printf("a = %3d\n", a);
    return 0;
}

The results of running this program are as follows

Execution Result
a = 98
a = 0

If the values of the same variable, a, were exchanged, then of course the result should remain the same, but
This method results in 0.
In this method, a and b in the macro are always the same value, so it is natural that subtraction would result in 0.
Incidentally, the method using exclusive disjunction also yields 0.

You might think there's no such thing as interchanging the same variable.
In fact, in a sorting program, when exchanging array[i] and array[j], if i == j, then
This can happen. Moreover, most of the uses of SWAP are for sorting programs.

There's nothing we can do about this problem, so we generally don't seem to go any further into it.
The author wants to solve this problem by force, too, and uses the method with the && operator.
The && operator has the property that if the immediately preceding expression is false, the subsequent expression will not be executed.
The following macro is a SWAP macro that takes advantage of the && operator property.

Source code
 #define SWAP(a, b) ((a ! = b) && (a += b, b = a - b, a -= b))

This macro performs the exchange only when the values of a and b are different.
In other words, if a and b are the same variable, they are not exchanged and remain the same.
However, one might say that it is easier to make it a function than to do this.

Alternatively, if you do not want to depend on the nature of the operator, you can use the ternary operator.

Source code
 #define SWAP(a, b) ((a ! = b) ? (a += b, b = a - b, a -= b) : 0)

The latter half of the 0 is a dummy value for grammatical consistency.
However, some compilers may warn you that it is a meaningless expression.
With these macros, variables of any type (even real numbers) can be exchanged, but
The only variable that cannot be exchanged is a pointer type variable that cannot be added or subtracted.

If you don't use pointer variables, you can make a SWAP macro, but
The only way to exchange pointer variables is inevitably to implement it by the function shown at the beginning.
And the trouble is that sometimes pointers are exchanged in sorting programs.

Furthermore, when exchanging real values, there is a potential for kerf loss.
For example, if the value of variable a is so huge and the value of b is so miniscule, then
Calculating a+b could result in rounding and the result being the same as a.
Therefore, it cannot be used when accuracy is required.

In the end, a temporary variable is inevitably needed to reliably exchange values.
To do so, the variable must be declared in the macro.

Since macros are merely replacements, variables can be declared by specifying their type.
You can also avoid variable name collisions by enclosing them in {} to block them.
Specifically, it looks like this

Source code
 #define SWAP(type,a,b) { type temp = a; a = b; b = temp; }

This macro is a little less convenient because it requires the type to be specified as the first argument, but it can be used with
Any variable can be exchanged as long as the type is specified.
Of course, real values and pointer values can also be exchanged.

The following program is an example of using this macro to exchange variables.

Source code
 #include <stdio.h>

#define SWAP(type,a,b) { type temp = a; a = b; b = temp; }

int main(void)
{
    int a = 10,b = 100;
    printf("a = %3d : b = %3d\n",a,b);
    SWAP(int,a,b)
    printf("a = %3d : b = %3d\n",a,b);
    return 0;
}

The results of running this program are as follows

Execution Result
a = 10 : b = 100a = 100 : b = 10

Of course, the same variable works fine when specified.
Because this method encloses variable declarations in {}, the
The statement is complete without the ;;.
It is better not to put a ; at the end.

If you want to put a ; at the end
If you feel weird about not being able to add a ; at the end, you can use
#define swap(type,a,b) do{type _c;_c=a;a=b;b=_c;}while(0)
The macro alone is not a complete statement, so you can use
It will work with a ; at the end.



About this Site

The C language (bitter C), which is learned by suffering, is
This is the definitive C language introductory site.
It systematically explains the basic functions of the C language and
It is as complete as or better than any book on the market.

Part 0: Program Overview
  1. What is the program?
Chapter 2: How to write a program
  1. Writing Rules
  2. Writing conventions
  3. Exercise 2
Chapter 3: Display on Screen
  1. String display
  2. newline character
  3. Exercise 3
Chapter 4: Numeric Display and Calculation
  1. Numeric Display
  2. Basic Calculations
  3. Type of value
  4. Exercise 4
Chapter 5: Numerical Memory and Calculation
  1. Memorize values
  2. Variable Type
  3. Type conversion
  4. Numeric justification
  5. Exercise 5
Chapter 6: Input from the keyboard
  1. Functions for input
  2. Fear of Input
  3. Exercise 6
Chapter 9: Repetition with a fixed number of times
  1. Sentences that repeat themselves
  2. Loop Operation Mechanism
  3. Exercise 9
Chapter 10: Unknown number of repetitions
  1. Loop of unknown frequency
  2. input check
  3. Exercise 10
Chapter 13: Handling Multiple Variables at Once
  1. Multiple variables are handled together.
  2. How to use arrays
  3. Exercise 13
Chapter 19: Dynamic Arrays
  1. Create arrays at will
  2. Exercise 19
Chapter 20: Multiple Source Files
  1. Minimal division
  2. The Stone of Partition
  3. Exercise 20

Comment
COMMENT

Open the 💬 comment submission box