0

私はこの列挙型をcに持っています

列挙は Java のように 0..n になりますか?

typedef enum tag_result
{
   // Success:
   succeeded   = 0,
   no_error    = 0,

   // General errors
   general_errors,
      err_failed,
      err_no_memory,
      err_invalid_argument,
      err_aborted
} result;
4

6 に答える 6

3

はい。

実際、数値/インデックスに関しては、または-Javaが呼び出すように-序数Cはより柔軟であり、開始を定義するか、各列挙型の数値を定義することさえできます:

int main(int argc, char** argv)  
{ 
    printf("RED:   %d\n", (int) RED );
    printf("GREEN: %d\n", (int) GREEN );
    printf("BLUE:  %d\n", (int) BLUE );
    return 0;  
} 

enum colors { RED, GREEN, BLUE};

出力は次のようになります

RED:   0
GREEN: 1
BLUE:  2

enum colors { RED = 4, GREEN, BLUE};

出力は次のようになります

RED:   4
GREEN: 5
BLUE:  6

enum colors { RED = 1, GREEN = 3, BLUE = 5};

出力は次のようになります

RED:   1
GREEN: 3
BLUE:  5
于 2013-09-29T13:36:13.897 に答える
0

Yes. In C enums always start at 0 unless you explicitly specify another value. Any unspecified values will increase monotonically from the last specified value.

Note that the enum is only guaranteed to be an integer type large enough to represent the values in the enum. It might not be int. Some C compilers will use char or short for small enums.

于 2013-09-29T13:36:54.067 に答える
0

はい、デフォルトでは、最初の列挙子の値は 0 です。ただし、指定子で列挙子の値を明示的に設定することもできます。後続の列挙子には、最後の列挙子に 1 を加えた値の値が必要です。

enum demo {
   first,
   second = 4,
   third,
   fourth
};

ここでfirstは値が 0 になりますが、残りの 3 つの値は 4、5、6 になります。

于 2013-09-29T13:37:53.337 に答える
0

C 列挙型は int です。この言語は、name から int への置換を行うためのいくつかの構文を提供するだけです (およびコンパイラーが強制できる他のいくつかの項目)。

Java のような列挙型が必要な場合は、一連のグローバル オブジェクトを作成する必要があります。C では Java 列挙型コントラクトが強制されていないため、可能な限りそれらを実装する必要があります。

したがって、これは 2 つの点で問題を複雑にします。ここで、オブジェクトをシミュレートし、列挙型をシミュレートする必要があります (c で Java のような列挙型が必要な場合)。

オブジェクトをシミュレートするには、うまく機能するテクニックがいくつかあります。重要なのは、必要な機能だけを実装するのを早期にやめることです。追加する機能が増えるほど、次のことが難しくなります。

typedef struct tag_result {
   int enum_value;
   char* enum_name;
} result;

result* getEnumByValue(int index);

result* getEnumByName(char* name);

そして.cファイルに

// resize to match entries
int enum_limit = 5;
result enums[enum_limit];

// it is your responsibility to not duplicate values.
enums[0].enum_value = 0;
enums[0].enum_name = "invalid_argument";
enums[1].enum_value = 1;
enums[1].enum_name = "no_memory";

result* getEnumByName(char* name) {
  int index;
  for (index = 0; index < enum_limit; index++) {
     if (strcmp(enums[index].enum_name, name)) {
       return enums[index];
     }
  }
  return 0;
}

result* getEnumByValue(int value) {
        int index;
  for (index = 0; index < enum_limit; index++) {
     if (enums[index].enum_value == value) {
       return enums[index];
     }
  }
  return 0;
}

ここで、カプセル化が必要な場合は、構造体を 2 つの部分 (1 つは公開、もう 1 つは非表示) に分割できます。最初の手法は、 のみを公開しtypedef struct s_result result、構造体のレイアウトを で定義できるようにすること.hです。最初は少しトリッキーですが、インクルードによって何も公開されないことが保証され、.cファイルへのフル アクセスが提供されます。この手法を使用する場合は、アクセサー メソッドを追加する必要があります。

int getResultValue(result* item) {
   return (*item).enum_value;
}

char* getResultName(result* item) {
   return (*item).enum_name;
}

一部の人々はこれをさらに掘り下げ、「パブリック」ヘッダーと「プライベート」ヘッダーがあります。一方の構造体が他方の構造体を参照している (void* ポインターによって隠されている)。アイデアは、「プライベート」ヘッダー ポインターの型を公開しないことでデータを非表示にすることです。当然、ビットをつなぎ合わせるには、配線を理解するコンストラクターが必要です。

result* new_resultEnum(int value, char* name) {
  result* newItem = (result*)malloc(sizeof(struct s_result));
  (*newItem).private = (p_result*)malloc(sizeof(struct s_p_result));
  (*newItem).private.enum_value = value;
  (*newItem).private.enum_name = name;
  return newItem;
}

このような手法を使用すると、C の関数ポインターを介してメンバー メソッドを簡単に追加できます (ただし、構文は少し難しくなります)。

  ... added to the constructor above ...
  (*newItem).getValue = result_getValue;

「getValue」メソッドを公開します。注意点が 1 つあります。C で "this" ポインターを渡す良い方法は実際にはありません。メンバー関数には、構造内にあることを "認識" する機能と、その構造がどこから始まるかを "認識する" 機能がないためです。はい、回避策はありますが、時間と費用がかかり始めます。私は通常、気にしないだけなので、このようなコードは非常に一般的です。

  result* myresult;
  (*myresult).getValue(myresult);

表面のより深い傷を気に入っていただければ幸いですが、メンバー関数よりもずっと早く停止する必要があります。そしておそらく、ポリモーフィシムの実装よりもずっと早く停止する必要がありました:)

于 2013-09-29T14:11:01.173 に答える