《代码的未来》第 2 章笔记

这里有一个对于 C 语言中 qsort() 函数的经典讲解。遂记录之。

/**
 * 《代码的未来》2.6 图3 关于 C 语言 qsort 使用的一种典型示例
 */
#include <stdio.h>
#include <stdlib.h>

int icmp(const void *a, const void *b)
{
    int x = *(int*)a; // 先把 a 转成指向 int 型的指针,之后再把它的值给解出来
    int y = *(int*)b;

    if (x == y) return 0;
    if (x > y) return -1;
    return 1;
}

int main(int argc, char **argv)
{
    int ary[] = {4, 7, 1, 2};
    const size_t alen = sizeof(ary) / sizeof(int); // 这里是为了实现通用性 ① ②
    size_t i;

    // 排序前
    for (i = 0; i < alen; i++) {
        printf("ary[%d] = %d ", i, ary[i]);
    }
    printf("\n");
    qsort(ary, alen, sizeof(int), icmp); // ③
    // 排序后,注意,这里的顺序是降序
    for (i = 0; i < alen; i++) {
        printf("ary[%d] = %d ", i, ary[i]);
    }
}

输出:
ary[0] = 4 ary[1] = 7 ary[2] = 1 ary[3] = 2 
ary[0] = 7 ary[1] = 4 ary[2] = 2 ary[3] = 1 

size_t,在 CLion 中查看源码可以得到:

20210222215842

20210222215913

因为我的机器是 64 位系统,所以 size_tunsigned long long 类型也就不足为奇。

贴一段《C Primer Plus》上关于 long long 类型的讲解:

现在,个人计算机上最常见的设置是,long long 占 64 位,long 占 32 位,short 占 16 位,int 占 16 位或 32 位(依计算机的自然字长而定)。原则上,这 4 种类型代表 4 种不同的大小,但是在实际使用中,有些类型之间通常有重叠。

C 标准对基本数据类型只规定了允许的最小大小。对于 16 位机,short 和 int 的最小取值范围是 [−32768,32767];对于 32 位机,long 的最小取值范围是 [−2147483648,2147483647]。对于 unsigned short 和 unsigned int,最小取值范围是 [0,65535];对于 unsigned long,最小取值范围是 [0,4294967295]。long long 类型是为了支持 64 位的需求,最小取值范围是 [−9223372036854775808,9223372036854775807];unsigned long long 的最小取值范围是 [0,18446744073709551615]。如果要开支票,这个数是一千八百亿亿六千七百四十四万亿零七百三十七亿零九百五十五万一千六百一十五。但是,谁会去数?

所以,用这个类型来记录 size 我想应该是很合适吧。毕竟范围这么广。

② 关于 sizeof 也有些淡忘,这是一个操作符,我们只需要理解它可以计算变量或者数据类型等所占的内存大小(字节)即可。

③ 最重要的,就是这个 qsort() 函数了。

我们先来看函数的声明:

void qsort(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *));
  • 参数 base,它的类型是 void *,这是为了方便给各种数据数组进行排序。
  • 参数 nmembe,元素数量。
  • 参数 size,待排序数据其类型的大小。
  • 参数 compar 是指向一个带两个参数的函数的指针。代表了排序的规则。比如,上面的例子中,就是降序规则。

由此,实现了算法的通用化。

posted @ 2021-02-22 22:31  模糊计算士  阅读(59)  评论(0编辑  收藏  举报