8

つまり、私が持っているのは、utils.hで作成したヘッダーファイルを含むファイルmain.cであり、ソースファイルutils.cの関数への前方参照が含まれています。

utils.cの場合:

文字列の配列を引数として受け取り、それをメニューとして出力する関数があります。

void showMenu(const char *menu[])
{
    int menulen = sizeof(menu)/sizeof(*menu);

    int i;
    for(i = 0; i < menulen; i++)
    {
        printf("[%d] .. %s\n", (i+1), menu[i]);
    }
}

main.c:

私は単にこの関数を呼び出します:

const char *menu[] =
{
        "Customers",
        "Orders",
        "Products"
};

int main(void)
{
    showTitle("Customer Orders System");
    int menulen = sizeof(menu)/sizeof(*menu);
    showMenu(menu);
    getch();
}

私の問題:

私のshowMenu関数は、配列の長さを計算し、それを反復処理して文字列を出力しています。これは、関数がmain.cにあるときに機能していましたが、このプロジェクトを個別のファイルに整理する必要があります。

現在、長さは1として計算されています。デバッグを行った後、これはポインター関連の問題だと思いますが、解決したようです。呼び出し後のshowMenuの引数はタイプです

const char** menu

元の配列の最初の要素だけがあります。

引数を延期し、配列のポインターを渡して、両方を同時に実行してみました。
不思議なことに、同じコード行がmain関数で機能します。関数に長さの配列引数を追加して、この問題を解決する必要は本当にありません。

どんな助けでも大歓迎です。

4

1 に答える 1

9

これは、配列があなたのような関数に渡されると最初の要素へのポインターに崩壊し、要素の数に関する情報が保持されないためです。配列が宣言されているスコープでは、この減衰は発生していないため、sizeof機能します。

追加の引数として配列の長さを追加するか、配列が適切なセンチネル値で終了していることを確認する必要があります。よく使われる値の 1 つは ですNULL。つまり、最後の有効なインデックスが、値がNULLである文字列ポインタを保持していることを確認します。これは、「これ以上データがありません。停止します」を示します。

const char *menu[] =
{
    "Customers",
    "Orders",
    "Products",
    NULL /* This is a sentinel, to mark the end of the array. */
};
于 2012-11-27T11:58:13.483 に答える