C 語言中的排序函式

Jinku Hu 2023年1月30日 2021年2月7日
  1. 使用 qsort 函式對 C 語言中的整數陣列進行排序
  2. 使用 qsort 函式對 C 語言中的字串陣列進行排序
C 語言中的排序函式

本文將介紹幾種在 C 語言中使用標準庫排序函式的方法。

使用 qsort 函式對 C 語言中的整數陣列進行排序

qsort 函式為不同的資料元素陣列實現了某種通用的排序操作。也就是說,qsort 將函式指標作為第四個引數,傳遞給定元素陣列的比較函式。在這種情況下,我們實現了 intCompare 函式來使用 qsort 比較整陣列。注意,intCompare 應該具有 qsort 原型指定的型別 - int (*compar)(const void *, const void *)。因此,我們首先將 p1/p2 引數轉換為 int 指標,然後再去引用它們來訪問值本身。如果第一個引數小於另一個引數,比較函式的返回值必須是小於 0 的整數,如果前者大於後者,則返回大於 0 的整數,而相等則返回 0。

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

static int intCompare(const void *p1, const void *p2)
{
    int int_a = * ( (int*) p1 );
    int int_b = * ( (int*) p2 );

    if ( int_a == int_b ) return 0;
    else if ( int_a < int_b ) return -1;
    else return 1;
}

void printIntegers(int arr[], size_t size)
{
    for (size_t i = 0; i < size; i++)
        printf("%4d | ", arr[i]);
    printf("\n");
}

int main(int argc, char *argv[]) {
    int arr2[] = {53, 32, 12, 52, 87, 43, 93, 23};

    printIntegers(arr2, 8);
    qsort(arr2, 8, sizeof(int), intCompare);
    printIntegers(arr2, 8);

    exit(EXIT_SUCCESS);
}

輸出:

53 |   32 |   12 |   52 |   87 |   43 |   93 |   23 |
12 |   23 |   32 |   43 |   52 |   53 |   87 |   93 |

使用 qsort 函式對 C 語言中的字串陣列進行排序

qsort 可以按升序對字串陣列進行排序,strcmp 作為比較函式。在這種情況下,我們宣告並初始化了 char 指標陣列,只要呼叫 qsort 函式,就可以對其元素進行排序。請注意,鑄造和去引用是比較函式的必要部分,因為它將兩個引數都作為 void 指標型別。

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

static int stringCompare(const void *p1, const void *p2)
{
    return strcmp(* (char * const *) p1, * (char * const *) p2);
}

void printStrings(char *arr[], size_t size)
{
    for (size_t i = 0; i < size; i++)
        printf("%10s | ", arr[i]);
    printf("\n");
}

int main(int argc, char *argv[]) {
    char *arr[] = {"jello",
                   "hello",
                   "mello",
                   "zello",
                   "aello"};

    printStrings(arr, 5);
    qsort(arr, 5, sizeof(char *), stringCompare);
    printStrings(arr, 5);

    exit(EXIT_SUCCESS);
}

輸出:

jello |      hello |      mello |      zello |      aello |
aello |      hello |      jello |      mello |      zello |

或者,我們可以重新實現前面的示例程式碼,讓使用者提供帶有程式引數的字串陣列,然後將排序後的陣列列印出來作為輸出。這一次,在繼續呼叫 qsort 之前,必須檢查是否有足夠的引數傳遞給排序。注意,stringCompare 函式直接返回 strcmp 呼叫的值,因為後者與 qsort 的比較函式的返回值規格相同。

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

static int stringCompare(const void *p1, const void *p2)
{
    return strcmp(* (char * const *) p1, * (char * const *) p2);
}

void printStrings(char *arr[], size_t size)
{
    for (size_t i = 0; i < size; i++)
        printf("%10s | ", arr[i]);
    printf("\n");
}

int main(int argc, char *argv[]) {

    if (argc < 3) {
        printf("Usage: ./program string_0 string_1 string_2...\n");
        exit(EXIT_FAILURE);
    }

    printStrings(argv+1, argc-1);
    qsort(argv+1, argc-1, sizeof(char *), stringCompare);
    printStrings(argv+1, argc-1);

    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