簡體   English   中英

使用C ++編程語言排序示例

[英]Sort example from C++ Programming Language

我正在使用“ 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));

}

誰能解釋這些對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;

原因 void指針轉換為char球是因為你不能對指針運算void*

指針算術以指針指向的對象大小單位 因此,要執行指針算術運算,編譯器需要知道指針的類型 ,以便它知道如何對其值進行加減。

對於void*這是不可能的,因為void沒有大小。 通過接受void*參數,原始類型已丟失。

為了解決這個問題,算法將void*強制轉換為char* char*工作在一個大小單位。 然后,該函數希望用戶將每個元素的實際大小作為另一個參數傳遞。

編譯器可以輕松地對所得的char*進行算術運算。

因為ssort()函數不知道元素的類型 ,所以調用者還需要傳遞自己的函數來進行元素之間的比較,從而對元素進行排序。 請注意, 傳入的函數將void*參數轉換為正確的類型。

之所以ssort()是因為調用ssort()函數的人知道要排序的類型 ,而ssort()函數則不需要。

這給函數調用者帶來了很多負擔,並且存在很多導致細微或不細微錯誤的錯誤空間。

C++ 的瘟疫一樣,避免此類編程

總結一下:

ssort()函數將void*強制轉換為char*以便它可以執行指針算術來定位需要比較的元素。

調用者傳入自己的函數(cmp),該函數將void*強制轉換為正確的類型以進行比較。

static_cast<T>只是嘗試將類型轉換為T 看這里的例子-

float f = 12.3;
float* pf = &f;

// static cast<>
// OK, n = 12
int n = static_cast<int>(f);
// Error, types pointed to are unrelated
//int* pn = static_cast<int*>(pf);
// OK
void* pv = static_cast<void*>(pf);
// OK, but *pn2 is rubbish
int* pn2 = static_cast<int*>(pv);

// reinterpret_cast<>
// Error, the compiler know you should
// call static_cast<>
//int i = reinterpret_cast<int>(f);
// OK, but *pn is actually rubbish, same as *pn2
int* pi = reinterpret_cast<int*>(pf);

禮貌: 靜態演員實際在做什么
並且您不能使用char*指向任何類型的值。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM