我将在"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*指向任何类型的值?
请记住,这是一个示例,通过说明处理泛型时编程中的弱点来演示如何不在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*到正确的类型,以便作出比较.