1

私はちょうどDeitelからのこの例を見ていました:

#include <stdio.h>

struct card {
    char *face;
    char *suit;
};

int main( void )
{
    struct card aCard;
    struct card *cardPtr;
    aCard.face = "Aces";
    aCard.suit = "Spades";
    cardPtr = &aCard;

    printf( "%s%s%s\n%s%s%s\n%s%s%s\n", aCard.face, " of ", aCard.suit,
        cardPtr->face, " of ", cardPtr->suit,
        ( *cardPtr ).face, " of ", ( *cardPtr ).suit
    );

    system("pause");
    return 0;
}

char *charへのポインタがあるようですが、 ...を使用して文字列を保存できるとは思っていませんでした。

問題は、メモリはここでどのように処理されるかということです。なぜなら、のようなものは見当たらなかったからですchar word[50]

4

3 に答える 3

5

コンパイラは、リテラルを格納するのに十分な大きさのメモリ位置を予約し、そのアドレスをポインタに割り当てます。その後、通常のように使用できますchar *。注意点の1つは、それが指すメモリを変更できないことです。

char *str = "This is the end";
printf("%s\n", str);

str[5] = 0; /* Illegal. */

ちなみに、このCFAQでも問題について説明しています。

于 2012-07-03T19:54:12.067 に答える
1

文字列定数"Aces"など"Spades"は、コンパイル時のリテラルだけではありません。コンパイラは、これらのスペースを(通常は読み取り専用の)プログラムメモリに割り当てます。

于 2012-07-03T19:56:53.643 に答える
0

aCard.face="エース"; aCard.suit="スペード"; 文字列リテラルを保持するコンパイラによって異なります。読み取り専用セグメントの場合、それを変更するとセグメンテーション違反が発生します。たとえば、スタックセグメントで書き込み可能な場合は、変更できます。したがって、動作は未定義です!!

于 2012-10-08T09:10:24.480 に答える