1

次のポインターを宣言したコンパイラーの字句解析でいくつかの問題に直面しています

char *words[29]={
        "program",
        "label",
        "integer",
        "word",
        "char",
        "byte",
        "shortint",
        "logint",
        "real",
        "single",
        "double",
        "string",
        "boolean",
        "var",
        "procedure",
        "function",
        "begin",
        "end",
        "if",
        "then",
        "else",
        "or",
        "and",
        "div",
        "not",
        "do",
        "while",
        "mod"
};
char message[30];

そして、関数でそれを使用しようとしました

            for(handle=0;(&words[handle] != NULL);handle++)
            {
                message = &words[handle];
                if(!strcmp(token,message))
                    message='words';
            }

しかし、実行しようとすると次のエラーが表示されます。

About (line message = &words[handle];) : warning C4047: '=' : 'char [30]' は 'char ** ' とは間接性のレベルが異なります

About (line message = &words[handle];): エラー C2106: '=': 左オペランドは左辺値でなければなりません

About (line message='words';) : エラー C2015: 定数の文字数が多すぎます

About (line message='words';): エラー C2106: '=': 左オペランドは左辺値でなければなりません

そのようにポインターを操作することはできませんか? 何か提案はありますか?

4

3 に答える 3

3

三つのこと:

  1. アンパサンド ( &) は関係ありません。の型words[handle]char *、つまり文字列なので、必要なものはすぐそこにあります。そのアドレスを取得する必要はありませんchar *

  2. 配列なので、に直接代入messageすることはできません。=C はあまり派手な言語ではありません。に変更できるmessageためchar *message、配列ではなくポインターになります。または、次のstrcpy(dst, src)ように関数を使用してコピーすることもできますstrcpy(message, "words")

  3. forループは配列NULL内のポインターを検索するため、wordsいつ停止するかがわかりますが、配列にはありませんNULL! 最後に追加する必要がありますNULL。書かれているように、通常の文字列しかないため、ループは探している null ポインターを見つけることができず、メモリの未知のゾーンに充電されます。

それが役立つことを願っています!

于 2009-06-24T01:36:48.650 に答える
3

そこにはいくつかのエラーがあります:

  • &words[handle] の代わりに words[handle] を使用
  • message = 'words' で何をしようとしていますか? ここには少なくとも 3 つのエラーがあります。文字列は単一引用符ではなく二重引用符を使用しています。message は定数です。変更できません。文字列をコピーするには、= 演算子だけでなく strcpy() を使用する必要があります
  • 文字列が等しい場合、strcmp() は 0 を返します。論理を逆にする必要があります
  • 配列の最後に NULL を含めるのを忘れました
于 2009-06-24T01:39:50.423 に答える
2

コードにいくつかの問題があります。まず、キーワードの配列を として宣言する必要がありますconst char *words[]。文字列定数を;char *なしでとして宣言するのは悪い習慣です。constこれは、レガシー コードが引き続きコンパイルされるようにするためだけに許可されています。

壊れやすいため、宣言で 29 の配列サイズを指定しないでください。空の括弧を使用して、コンパイラに配列サイズを把握させる必要があります。を実行することで配列のサイズを取得できますsizeof(words)/sizeof(words[0])。これは、要素を追加または削除しても正しい値ですwords

次に、forループが終了することはありません (ただし、ある時点でほぼ確実に segfault が発生します)。値のアドレスを取得しても null ポインターは返されないため、&words[handle] != NULL常に true になります。ループを反復する適切な方法は、エントリの数を数えることです。

for(handle = 0; handle < sizeof(words)/sizeof(words[0]); handle++)

message文字の配列として宣言されます。配列は代入できません。つまり、左辺値ではありません。配列に代入するstrcpy()場合は、(バッファ オーバーフローの可能性があるため、特定の場合を除いて推奨されません)、strncpy()memcpy()、またはstrncpy_s()(Windows でのみ使用可能) などを使用して、明示的にデータを配列にコピーする必要があります。

ただし、この場合、配列はまったく必要ありません。ポインターを割り当てたいだけです。代わりに宣言messageconst char *ます。適切にmessage宣言すると、次のようになります。

const char *message;
...
message = words[handle];
if(!strcmp(token, message))
    message = "words";

そこの最後のステートメントでは、二重引用符を使用しwordsて文字列定数にする必要があります。一重引用符は、単一文字の定数用です (例: 'A')。技術的には複数の文字を含めることができますが、結果の整数定数のエンディアンは実装定義であり、この場合は必要なものではありません。

また、あなたがmessage = "words";ラインで何をしようとしているのかよくわかりません。変数で巧妙なトリックを実行しようとしている場合はwords、すぐに停止してください。うまくいきません。C には、いかなる種類のリフレクションもありません。

于 2009-06-24T01:42:02.477 に答える