在 C 語言中實現交換函式

Jinku Hu 2023年1月30日 2021年2月28日
  1. 使用臨時變數在 C 語言中實現交換函式的方法
  2. 使用算術運算來實現 C 語言中的交換函式
  3. 在 C 語言中使用按位異或運算實現交換函式
  4. 在 C 語言中使用按位異或操作和巨集來實現交換函式
在 C 語言中實現交換函式

本文將介紹幾種在 C 語言中實現交換函式的方法。

使用臨時變數在 C 語言中實現交換函式的方法

交換函式是對變數進行的典型操作。目前還沒有像 C++ 那樣的標準庫函式提供這個函式,因為 C++ 有 std::swap 函式。在本文中,我們實現了針對積分值的 swap 函式;即大部分函式取 long int 型別的引數,但人們總是可以為不同型別定義多個原型,並使用巨集擴充套件來保證通用功能。下面的例子演示了使用臨時變數的交換函式。請注意,儘管這是最簡單的實現,但在下面列出的其他版本中,這個版本相對來說是最快的(當使用編譯器優化時)。

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

void swap(long *x, long *y)
{
    long tmp = *x;
    *x = *y;
    *y = tmp;
}

int main(int argc, char *argv[])
{
    if (argc != 3) {
        printf("Usage: ./program first_number second_number/n");
        return 1;
    }

    long x = strtol(argv[1], NULL, 0);
    long y = strtol(argv[2], NULL, 0);

    printf("x:%ld, y:%ld\n", x, y);
    if (x != y)
        swap(&x, &y);
    printf("x:%ld, y:%ld\n\n", x, y);

    exit(EXIT_SUCCESS);
}

示例命令:

./program 123 432

輸出:

x:123, y:432
x:432, y:123

使用算術運算來實現 C 語言中的交換函式

另外,也可以只用加法和減法運算實現交換函式。我們在函式中對傳遞的指標進行操作,從而直接修改引數值。在 main 函式中,在呼叫 swap 函式之前有一個 if 條件,以避免運算元相等時的呼叫。

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

void swap(long *x, long *y)
{
    *x = *x + *y;
    *y = *x - *y;
    *x = *x - *y;
}

int main(int argc, char *argv[])
{
    if (argc != 3) {
        printf("Usage: ./program first_number second_number/n");
        return 1;
    }

    long x = strtol(argv[1], NULL, 0);
    long y = strtol(argv[2], NULL, 0);

    printf("x:%ld, y:%ld\n", x, y);
    if (x != y)
        swap(&x, &y);
    printf("x:%ld, y:%ld\n\n", x, y);

    exit(EXIT_SUCCESS);
}

在 C 語言中使用按位異或運算實現交換函式

交換函式最棘手也是略顯複雜的實現方式就是使用按位異或操作。請注意,這個版本不像前面的例子那樣需要第三個變數。首先,我們將給定整數的異或運算結果儲存在它們的一個位置。然後,我們將儲存的值(y)與另一個整數進行 XOR,並將結果儲存在後者的位置上。最後,兩個變數再進行一次異或運算,結果儲存在第一個修改的變數中-本例中的 y。當編譯時,這種實現涉及更多的機器程式碼指令,因此,產生了一個更多的計算密集型解決方案。

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

void swap(long *x, long *y)
{
    *y = *x ^ *y;
    *x = *x ^ *y;
    *y = *x ^ *y;
}

int main(int argc, char *argv[])
{
    if (argc != 3) {
        printf("Usage: ./program first_number second_number/n");
        return 1;
    }

    long x = strtol(argv[1], NULL, 0);
    long y = strtol(argv[2], NULL, 0);

    printf("x:%ld, y:%ld\n", x, y);
    if (x != y)
        swap(&x, &y);
    printf("x:%ld, y:%ld\n\n", x, y);

    exit(EXIT_SUCCESS);
}

在 C 語言中使用按位異或操作和巨集來實現交換函式

如前面的例子所示,XOR 交換函式也可以用類似函式的巨集來實現。需要注意的是,需要檢查兩個運算元是否是同一個物件,否則,巨集會將物件賦值為零,從而導致錯誤的輸出。這個檢查是用:條件來實現的,只有這樣,我們才會執行類似前面實現的 XOR 交換演算法。不過要注意,這個類似函式的巨集只能處理整數值。

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

#define XORSWAP(a, b)   ((&(a) == &(b)) ? (a) : ((a)^=(b),(b)^=(a),(a)^=(b)))

int main(int argc, char *argv[])
{
    if (argc != 3) {
        printf("Usage: ./program first_number second_number/n");
        return 1;
    }

    long x = strtol(argv[1], NULL, 0);
    long y = strtol(argv[2], NULL, 0);

    printf("x:%ld, y:%ld\n", x, y);
    XORSWAP(x, y);
    printf("x:%ld, y:%ld\n", x, y);

    exit(EXIT_SUCCESS);
}
Author: Jinku Hu
Jinku Hu avatar Jinku Hu avatar

Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.

LinkedIn