6

私は K&R 第 2 版、第 5 章に取り組んでいます。

87 ページで、文字配列へのポインターが次のように紹介されています。

char *pmessage;
pmessage = "Now is the time";

pmessageそれが単一の文字へのポインタではなく、文字配列へのポインタであることをどうやって知るのでしょうか?

拡張するには、94 ページで、次の関数が定義されています。

/* month_name: return the name of the n-th month */
char *month_name(int n)
{
    static char *name[] = {
        "Illegal month",
        "January", "February", "March",
        ...
    };

    return (n < 1 || n > 12) ? name[0] : name[n];
}

上記の関数宣言が単に提供された場合、単一の文字または文字配列が返されるかどうかをどのように知ることができますか?

from の戻り値month_name()が文字配列であると想定し、a が検出されるまでそれを繰り返したNULLとしても、戻り値が実際には 1 文字だった場合、セグメンテーション違反の可能性はありませんか?

誰かが、単一文字と文字配列へのポインターの宣言と割り当て、関数での使用法、および返された識別を示してもらえますか?

4

4 に答える 4

4

したがって、静的な保存期間を持つ char の配列である文字列リテラルがあります。

"Now is the time"

ほとんどのコンテキストでは、配列は最初の要素へのポインターに崩壊します。これがここで発生します。

pmessage = "Now is the time";

入力と出力に何が期待できるかを理解できるように、インターフェースを設計して文書化する必要があります。何が指されているかの性質を伝えるランタイム情報はありません。

たとえば、strtok の man ページを見ると、次のように表示されます。

strtok() を呼び出すたびに、次のトークンを含む null で終わる文字列へのポインターが返されます。

そのため、プログラマーは何を期待するかを正確に把握し、それに応じて結果を処理します。

単一の char へのポインターがあり、代わりにC スタイルの文字列のような場合、範囲外のメモリにアクセスするため、未定義の動作が発生します。セグメンテーション違反は 1 つの可能性ですが、未定義であることは結果が予測できないことを意味します。

于 2014-03-14T12:06:33.937 に答える
2

何が

char *pmessage;
pmessage = "Now is the time";  

平均?は、文字列リテラル の最初の文字を指すポインターとして
char *pmessage;宣言したことを意味します。 pmessagechar
pmessage = "Now is the time";pmessageNow is the time

関数から戻るpmessageと、文字列リテラルへのポインターが返されます。指定子を使用して
印刷すると印刷されpmessage、指定して印刷すると文字列リテラル全体が印刷されます。 %cN%s

printf("%c\n", *N);     // 'N' will be printed
printf("%s\n", N);      //  "Now is the time" will be printed 
于 2014-03-14T12:06:19.727 に答える
1

pmessage が文字配列へのポインタであり、単一の文字へのポインタではないことをどのように知ることができますか?

あなたはそうしない。少なくとも、ポインター値自体から、それが単一の要素を指しているのかchar、配列の最初の要素を指しているのかを判断する方法はありませんchar。どちらの方法でも使用できます。

コンテキストに依存するか、ポインターの使用方法を明示的に指定する必要があります。たとえばscanf、ポインターが単一の を指しているかどうかを判断するために、さまざまな変換指定子を使用しますchar

char single_char;
scanf( " %c", &single_char );

またはの配列char:

char array_of_char[N];
scanf( "%s", &array_of_char[0] );

sizeofまたは 単項演算子のオペランドではない場合、または&宣言で別の配列を初期化するために使用されている文字列リテラルではない場合、「の N 要素配列」型の式は式Tに変換 (「減衰」) されることに注意してください。式Tの値は配列の最初の要素のアドレスになるため、最後の行も書き込むことができます

scanf( "%s", array_of_char );

この変換規則により、配列式を関数に渡すときはいつでも、関数が実際に受け取るのはポインター値です。実際、関数宣言は

void foo( char str[N] );

void foo( char str[] );

と同等です

void foo( char *str );

str3 つすべてが へのポインタとして扱われますchar

于 2014-03-14T15:22:53.493 に答える