5

このコードスニペットは、私が読んでいる本から手作業でコピーしたものです。

/* scmp: string compare of *p1 and *p2 */
int scmp(const void *p1, const void *p2)
{
        char *v1, *v2;
        v1 = *(char **) p1; 
        v2 = *(char **) p2; 

        return strcmp(v1, v2);
}

この関数は、文字列の配列をソートするためにqsortで使用されます。私が理解していないポイントは、なぜこの機能v1 = *(char **) p1;だけでなく、機能しないのかということです。?コンパイラはその割り当てを自動的に型キャストする必要があると思います。または、これを考慮してください:v1 = (char *) p1;v1 = p1;

/* scmp: string compare of *p1 and *p2 */
int scmp(const void *p1, const void *p2)
{
        return strcmp(p1, p2);
}

私は(私はひどく間違っているかもしれませんが)コンパイラーはそれが期待するものなので、型キャストp1p2て入力することになっていると思います。char *strcmp(char *, char *)

要約すると、問題はなぜv1 = *(char **) p1ですか?

4

1 に答える 1

7

qsort比較する必要がある要素へのポインターを比較関数に渡します。C にはテンプレートがないため、このポインターは残酷に a にキャストされますconst void *( void *C では、「これはある種のポインター」を意味するだけであり、何かを行うには、実際の型にキャストし直す必要があります)。

ここで、文字列の配列をソートする場合、比較する必要がある各要素はchar *; です。ただしqsort、比較関数に各要素へのポインターscmpを渡すため、実際に受け取るのは a char **(文字列の最初の文字へのポインターへのポインター) でconst void *あり、比較関数の署名がそうしているため、 a にキャストされます。

したがって、 を取得するchar *には、まずパラメーターを実際の型 ( ) に変換し、char **次にこのポインターを逆参照して、char *比較する実際の型を取得する必要があります。

(ただし、 const-correctness の観点からは、 にキャストする方が正しいでしょうconst char **)

于 2012-04-28T13:59:39.097 に答える