2017-12-01 18 views
4

私はqsortのさまざまな実装を見てきましたが、ここに見つかったソースにはわかりません(https://code.woboq.org/userspace/glibc/stdlib/qsort.c.html)という行があります。それは関数ポインタ宣言のように見えます。私はどんな助けにも感謝しています。私は必要なだけ多くのコードを記述していますが(私はその行に記されています)、私はその質問に答えると思います。私に知らせてください、ありがとうございました。qsortのCコードの行を説明してください

typedef struct 
{ 
    char *lo; 
    char *hi; 

} stack_node; 


void _quicksort (void *const pbase, size_t total_elems, size_t size, cmp_t cmp, void *arg) 
{ 

    char *base_ptr = (char *) pbase; 

    const size_t max_thresh = 4 * size; 

    if (total_elems == 0) 

     return; 

    if (total_elems > 4) 
    { 
     char *lo = base_ptr; 
     char *hi = &lo[size * (total_elems - 1)]; 
     stack_node stack[(8 * sizeof(size_t))]; 
     stack_node *top = stack; 

     /* Line below is a function pointer declaration? Initializes struct? */ 

     ((void) ((top->lo = (((void*)0))), (top->hi = (((void*)0))), ++top)); 

     while ((stack < top)) 
     { 
      char *left_ptr; 
      char *right_ptr; 

      char *mid = lo + size * ((hi - lo)/size >> 1); 

...コードが

+0

リンクのコードにこのような行はありません。それは 'PUSH(NULL、NULL); 'とだけ言います。あなたはこのバージョンをどこで手に入れましたか、なぜこの形式で見ていますか? – AnT

+0

上記のコードはポスト前処理です –

答えて

7

に行くいいえ、それは関数ポインタの宣言ではありません。それはちょうど

top->lo = 0; 
top->hi = 0; 
++top; 

あなたはその後、不要なキャスト

top->lo = (void *) 0, top->hi = (void *) 0, ++top; 

を追加,オペレータ

top->lo = 0, top->hi = 0, ++top; 

を使用して単一の発現文として上記を書き換えることができると言うための複雑な方法と房のです冗長()s

(top->lo = (((void *) 0))), (top->hi = (((void *) 0))), ++top; 

、その後は

((void) ((top->lo = (((void *) 0))), (top->hi = (((void *) 0))), ++top)); 

(「未使用」式の結果のことについて、潜在的なコンパイラの警告を抑制するために、例えば)(void)に全体をキャストして、今、あなたはあなたの元のバージョンを持っています。

なぜ誰かが,という演算子と冗長な大量の()という奇妙な構文を使用することに決めたのは私には分かりません。マクロ展開のように見えます。すでに前処理されたコードなのでしょうか? ((void *) 0)の部分は、標準のNULLマクロのプリプロセッサの置き換えになる可能性があります。私たちはラインが実際に特定の

/* The next 4 #defines implement a very fast in-line stack abstraction. */ 
/* The stack needs log (total_elements) entries (we could even subtract 
    log(MAX_THRESH)). Since total_elements has type size_t, we get as 
    upper bound for log (total_elements): 
    bits per byte (CHAR_BIT) * sizeof(size_t). */ 

#define STACK_SIZE  (CHAR_BIT * sizeof(size_t)) 
#define PUSH(low, high) ((void) ((top->lo = (low)), (top->hi = (high)), ++top)) 
#define POP(low, high) ((void) (--top, (low = top->lo), (high = top->hi))) 
#define STACK_NOT_EMPTY (stack < top) 

とコード内のマクロ定義であることを発見するURLを見てみると

+0

それは多くの助けになります。ありがとう。ポストマクロ展開です。 –

2

は、実際にPUSHの定義に表示され、その大要はPOPに表示されます。余分な()の使用は、++top--topが正しい順序でinlineとなるようにすることです。我々は著作権(C)1991を参照するとき

それがこの方法を実装しています理由は明確である - qsort.cの上部に2017メッセージを... 1991年コンパイラは、おそらくインライン化機能で本当に嫌でした。

関連する問題