1
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <assert.h>

    static int cmpstringp(const void *p1, const void *p2)
    {
       /* The actual arguments to this function are "pointers to
          pointers to char", but strcmp(3) arguments are "pointers
          to char", hence the following cast plus dereference */

        return strcmp(* (char * const *) p1, * (char * const *) p2);
    }

    int main(int argc, char *argv[])
    {
        int j;

        assert(argc > 1);

        qsort(&argv[1], argc - 1, sizeof(argv[1]), cmpstringp);

        for (j = 1; j < argc; j++)
            puts(argv[j]);
        exit(EXIT_SUCCESS);
    }

私はこの部分と混同しています:

        return strcmp(* (char * const *) p1, * (char * const *) p2);

なぜ彼らはこれをしたのですか?なぜ彼らはこれをしなかったのですか:(const char**)または(const char * const*)? を一度逆参照すると、const char へのポインターを取得しません(const char**)か? 2 番目のものを逆参照すると、const char を指す const ポインターが得られません。これらは両方とも、strcmp()const chars を指す 2 つのポインターを要求しているように見えます。マニュアルページが const 以外のものを指す const ポインターを提供しているように見えるものは、strcmp()の宣言が求めているものではないようです。合法的であっても、関数にそのパラメーターに適合しないものを与えることは良い考えではないようです。何か不足していますか?

最後に、以下が少なくともエラー警告を生成しないのはなぜですか:

    auto const char * const ptr3 = *(const char **) ptr1; //where ptr1 is    
    of the form int foo(const void * ptr).

逆参照ptr1を一度行うと、const char へのポインターが得られますが、それ自体は const ではありません。ただし、ptr3定数です。では、なぜコンパイラは警告を生成しないのでしょうか? 何か不足していますか、それとも警告を生成してはならない理由がありますか?

4

2 に答える 2

0

あなたの質問の最初の部分、私はあなたがどこに置くかについていくらかの柔軟性があると思います、そしてconstそれは同じです。const char **char * const *

質問の2番目の部分では、任意のポインターをポインターに割り当てることができconstます。エラーを生成するのは逆の方向に進んでいます。明示的なキャストにより、コンパイラがポインタの元の型について持っていた知識がすべて削除されました。

于 2011-10-22T03:36:20.397 に答える