7

文字列をCの配列インデックスとして使用できますか?

例:文字列対応する値 "ONE" 1 "TWO" 2 "FIVE" 5 "TEN" 10

上記のリストの文字列が関数に渡される場合、関数は上記の対応する値を返す必要があります。これは、文字列をインデックスとして持つ定数配列を宣言することで実現できますか?

int *x;
x["ONE"]  = 1;
x["TWO"]  = 2;
x["FIVE"] = 5;
x["TEN"]  = 5;

return x["string received by the function"];

上記のロジックは期待どおりに機能しません。文字列インデックス付き配列を作成するために上記のロジックを実装するための回避策はありますか?

4

8 に答える 8

19

コンパイルされるかもしれませんが、動作しません。

あなたが何を達成しようとしているのかは完全には明らかではありません。連想配列が必要だと思います。その場合は、そのライブラリ実装を見つける必要があります。

列挙型のようなものを探していて、 C89に頼ることができる場合は、次のようなものを見てください。

enum cardsuit {
   CLUBS,
   DIAMONDS,
   HEARTS,
   SPADES
};

C89に頼ることができない場合は、いくつかのトリックを試してみてくださいtypedef

于 2009-01-06T11:57:59.040 に答える
10

あなたがすべきことには他にも優れた答えがあるので、私はあなたが何をしているのか、そしてなぜそれがコンパイルされて機能しないのかを説明したいと思いました。

Cでは、配列の参照は、配列またはポインターと、ある種の整数を使用して行われます。(x [1]では、xは配列で、1は整数です)。一体型を使用している限り、期待どおりに機能します。

整数ではないものがあるとします。その場合、C実装はそれを適切な型に変換できるかどうかを確認するので、配列と整数になります。このような場合、問題が発生します(C ++でのこれの少し洗練されたバージョンは、あなたよりも経験豊富な人々を混乱させています)。

Cでは、「one」のようなリテラル文字列はconst char *型であり、変更できない文字へのポインタを意味します。実際の値は、文字列が実際にメモリ内に存在する場所のメモリアドレスです。通常、このポインタ値には注意を払わず、文字列値を確認しますが、ここに落とし穴があります。

Cでは、任意のデータポインタをある種の整数に変換でき、自動的に変換されます。したがって、「one」のような文字列があり、その値はメモリアドレスを表す任意の数値です。Cがある種の整数を期待する場合に使用し、整数値などに変換されます。

したがって、これはx["ONE"]で起こっていることです。Cシステムは、文字列「ONE」をメモリのどこかに配置する必要があり、どこに配置してもかまいません。それはかなり大きなメモリアドレスを持つ場所である可能性が高く、おそらく数十億になります。x ["ONE"]を検出すると、その値を整数に変換しようとし、それを添え字として使用します。したがって、配列xにその境界をはるかに超えてアクセスしようとしているため、問題が発生しています。許可されていないメモリを使用しようとしていて、システムが停止するか、そのままにしておく必要のあるメモリのチャンクをいじくり回していると、後で不思議な方法で失敗する可能性があります。

于 2009-01-06T14:39:14.830 に答える
5

bsearch()が提供する関数を使用して、ルックアップ テーブルを簡単に作成できますstdlib.h。実際の例は次のとおりです。

#include <string.h>
#include <stdlib.h>
#include <stdio.h>

#define count(ARRAY) (sizeof(ARRAY)/sizeof(*ARRAY))

struct item
{
    const char * name;
    int value;
};

static _Bool sorted;

static struct item items[] =
{
    { "one", 1 },
    { "two", 2 },
    { "three", 3 },
    { "ten", 10 }
};

static int compare(const void * p1, const void * p2)
{
    return strcmp(*((const char **)p1), *((const char **)p2));
}

int get(const char * name)
{
    if(!sorted)
    {
        qsort(items, count(items), sizeof(*items), compare);
        sorted = 1;
    }

    struct item * item = bsearch(&name, items, count(items), sizeof(*items),
        compare);

    return item ? item->value : 0;
}

int main(int argc, char ** argv)
{
    int i;
    for(i = 1; i < argc; ++i)
        printf("%i\n", get(argv[i]));

    return 0;
}
于 2009-01-06T12:45:24.247 に答える
3

文字列を整数にマップする関数を作成するか、あるいは全体で列挙型を使用する必要があります(そして、おそらく列挙値を文字列にマップする関数)。

一般に、後者を実行する方が適切です。整数を渡すことで、実装が表現で使用される可能性のある文字列の詳細に依存しないようにします。たとえば、別の言語を話す人がこれらの文字列を口に合うようにする必要がある場合は、ローカリゼーション(翻訳)をどのように管理するかを考えてください。

于 2009-01-06T11:59:04.467 に答える
1

あなたが探しているのは、おそらく、いくつかのばかげた結果なしに、残念ながらCで同じシンタックスシュガーを提供できない連想配列に相当します。

ただし、提供できるのは、データがキー->値のペアに準拠している場合のハッシュマップです。必要なのは適切なハッシュ関数です。

ここにハッシュテーブルのまともな簡単な例があります:

http://www.cl.cam.ac.uk/~cwc22/hashtable/

于 2009-01-06T12:15:44.933 に答える
0

既に示したように、連想配列またはハッシュ マップ、または同等のものが必要です。そのようなコードの可能性のあるソースの 1 つは、Hanson の「C Interfaces and Implementations」です ( Google Codeのコード- 使用する前にライセンス条件などを再確認してください)。

于 2009-01-06T13:18:46.943 に答える
-2

「プレーンC」では、文字列をインデックスとして使用して模倣できますが、望むようにQUITEすることはできません。ただし、これが役立つことはめったになく、ほとんどの場合、コードを判読不能にする優れた方法です。あなたが望んでいるように見えるのは、文字列キーを辞書(または、必要に応じて「ハッシュテーブル」)に使用できるようにすることであり、Cにはそのための組み込みのデータ構造はありません。正確な設計は、あなたが何をするかによって異なります(実際、これが宿題の一部である場合は、本格的なハッシュ テーブルの実装を使用する必要さえないかもしれませんが、おそらくパフォーマンスの低い静的コーディングで済む可能性があります)。

a[b] コンストラクトの「インデックス位置」で文字列 (OK、char 配列) を使用する例:

int main (void)
{
  char *str = "This is a test string";
  int x;

  for (x=0; x < 12; x += 3)
    putchar(x[str]);

  printf("\n");

  return 0;
}

上記は、私が知る限り、適切に定義された出力 (文字列 "Tss ssi") を備えた正当な C です。これは、a[b] が *(a+b) と同じであると定義されているという事実に依存しています。

于 2009-01-06T12:44:14.187 に答える