从C++编程语言中排序示例

use*_*451 1 c++ static-cast

我将在"C++编程语言"中查看以下示例代码:

typedef int (*CFT) (const void*, const void*);

void ssort(void* base, size_t n, size_t sz, CFT cmp) {
    for (int gap = n / 2; 0 < gap; gap /= 2) {
        for (int i = gap; i < n; i++) {
            for (int j = i - gap; 0 <= j; j -= gap) {
                char* b = static_cast<char*>(base);
                char* pj = b + j * sz;
                char* pig = b + (j + gap) * sz;

                if (cmp(pig, pj) < 0) {
                    for (int k = 0; k < sz; k++) {
                        std::swap(pj[k], pig[k]);
                    }
                } else {
                    break;
                }
            }
        }
    }
}

int cmp(const void* a, const void* b) {
    return *(static_cast<const int*>(a)) - *(static_cast<const int*>(b));

}
Run Code Online (Sandbox Code Playgroud)

任何人都可以解释这些演员对char*的看法吗?我们如何使用char*指向任何类型的值?

Gal*_*lik 7

请记住,这是一个示例,通过说明处理泛型时编程中的弱点来演示如何不在C++中执行操作.C

Quote: C++编程语言(第4版第334页)

这种代码在C中很常见,但它并不是用C++表达这种算法的最优雅方式

然而:

char* b = static_cast<char*>(base);
char* pj = b + j * sz;
char* pig = b + (j + gap) * sz;
Run Code Online (Sandbox Code Playgroud)

理由void指针转换为char指针,是因为你不能做指针运算void*.

指针运算在单位中的大小物体的指针指向.因此,要进行指针运算,编译器需要知道指针的类型,以便它可以知道如何添加和减去其值.

这是不可能的,void*因为void没有大小.通过接受void*参数,原始类型已丢失.

为了解决这个问题,算法转换void*char*.将char* 在大小单位的作品一个.然后,该函数希望用户将每个元素的实际大小作为另一个参数传递.

编译器对结果进行算术运算没有问题char*.

因为ssort()函数不知道它正在排序的元素的类型,所以调用者还需要传递它们自己的函数来进行元素之间的比较.请注意,传入函数会将void*参数转换为正确的类型.

这是有效的,因为调用ssort()函数的人知道要排序的类型,而ssort()函数不需要.

这给函数调用者带来了很多负担,并且存在很多导致细微或不那么微妙的错误的错误空间.

这种类型的编程应该避免像瘟疫C++.

总结一下:

ssort()功能注塑void*char*,以便它可以做指针运算,以定位元件无需比较.

来电者通过在自己的函数(CMP)是注塑void*正确的类型,以便作出比较.