0

シリアル コマンド インタープリターを構築しようとしているので、コマンドを配列に格納したいと考えています。コマンド名と入力した内容を比較して関数を呼び出せるように、各コマンドに名前と関数ポインターを持たせたいと考えています。私はCが得意ではないので、助けてください!これが私がこれまでに持っているものです。

コマンド配列は、構造体の配列になります。各構造体には、文字列と関数ポインターがあります。ここにエラーがありますが、修正方法がわかりません。これらはメインの前に行われます。

typedef struct cmdStruct {
    char cmd[16];
    void (*cmdFuncPtr)(void);
}CmdStruct;

void (*ledFuncPtr)(void);
void (*cmd2FuncPtr)(void);

// assign pointers to functions
ledFuncPtr = &LedFunction;
cmd2FuncPtr = &Cmd2Function;

//build array of structs
CmdStruct cmdStructArray[] = cmdStructArray = { {"led",   ledFuncPtr   },
                                                {"cmd2",  cmd2FuncPtr  },  };

後で、構造体配列を調べて、受信したコマンドと比較します。

// go through the struct array to do string comparison on each struct's string member
for (int i = 0; i < sizeof(cmdStructArray); i++) {
    // string comparison of received command and string of struct
    if(strcmp(cmdStructArray[i].cmd, receivedCmd)==0) {
        // dereference function pointer
        (*cmdStructArray[i].cmdFuncPtr)(void);
    }
}

どの部分が間違っているのか、どうすれば修正できますか?

4

2 に答える 2

4

sizeof(cmdStructArray)要素単位ではなく、バイト単位です。

を使用しsizeof(cmdStructArray)/sizeof(cmdStructArray[0])ます。

于 2013-01-09T19:25:09.690 に答える
3

すでに指摘したように、あなたのサイクルは間違った回数の反復を行います。sizeof arrayは配列内の要素数を提供しますが、配列内のバイト数を提供します。sizeof array / sizeof *array要素の数を取得するには、計算する必要があります。

また、関数呼び出しの構文が無効です

 (*cmdStructArray[i].cmdFuncPtr)(void);

上記はコンパイルされません。void関数呼び出しで引数として指定することはできません。(void)構文は、関数宣言でのみ使用できます。関数がパラメーターを受け入れない場合、呼び出しは次のようになります。

 (*cmdStructArray[i].cmdFuncPtr)();

また、これもコンパイルされません

CmdStruct cmdStructArray[] = cmdStructArray = { {"led",   ledFuncPtr   },
                                                {"cmd2",  cmd2FuncPtr  },  };

なぜcmdStructArrayこの宣言で2回言及しているのですか?


いくつかの追加の、本質的に表面的な注意事項:

まず、コマンドはおそらくコンパイル時に認識される文字列リテラルになるため、構造体の最初のメンバーをconst char *char 配列ではなくポインターとして宣言できます。

typedef struct cmdStruct {
  const char *cmd;
  void (*cmdFuncPtr)(void);
} CmdStruct;

初期化構文は変更されません。16これにより、配列のサイズ (現在そこにあるもの)について心配する必要がなくなります。

第二に、配列を直接初期化する代わりに、関数ledFuncPtrへの中間ポインターを宣言しなければならなかった理由が明確ではありません。cmd2FuncPtrこれの目的は何でしたか

void (*ledFuncPtr)(void);
void (*cmd2FuncPtr)(void);

// assign pointers to functions
ledFuncPtr = &LedFunction;
cmd2FuncPtr = &Cmd2Function;

CmdStruct cmdStructArray[] = { {"led",   ledFuncPtr  },
                               {"cmd2",  cmd2FuncPtr }, };

単純にこれを行うことができたとき

CmdStruct cmdStructArray[] = { {"led",   &LedFunction  },
                               {"cmd2",  &Cmd2Function }, };

(紹介せずledFuncPtrcmd2FuncPtr)?

*第 3 に、関数ポインターでand&演算子を使用する必要はありません。これも効きます

CmdStruct cmdStructArray[] = { {"led",   LedFunction   },
                               {"cmd2",  Cmd2Function  }, };

cmdStructArray[i].cmdFuncPtr();

とにかく、これは純粋に表面的な問題であり、個人的な好みの問題です.

于 2013-01-09T19:36:10.923 に答える