よし、C++ のことはしばらく脇に置いておこう。C++ は C の単なるスーパーセットです (つまり、C で実行できることはすべて C++ でも実行できます)。それでは、plain-C に集中しましょう (それは私がよく知っている言語だからです)。C には列挙型があります。
enum fruit { apple, banana, cherry, peach, grape };
これは完全に正当な C であり、値は連続しており、apple の値は 0 で、banana の値は apple + 1 です。穴のある列挙型を作成できますが、このような穴を明示的に作成する場合に限ります。
enum fruit { apple = 0, banana, cherry = 20, peach, grape };
りんごは 0、バナナは 1、さくらんぼは 20、桃は 21、ぶどうは 22、1 から 20 までは未定義です。通常、穴は必要ありません。次のことができます。
enum fruit { apple = 0, banana, cherry, peach, grape };
enum fruit myFruit = banana;
myFruit++;
// myFruit is now cherry
printf("My fruit is cherry? %s\n", myFruit == cherry ? "YES" : "NO");
これにより、YES が出力されます。次のこともできます。
enum fruit { apple = 0, banana, cherry = 20, peach, grape };
enum fruit myFruit = banana;
myFruit++;
// myFruit is now cherry
printf("My fruit is cherry? %s\n", myFruit == cherry ? "YES" : "NO");
これは NO を出力し、myFruit の値は列挙定数のいずれとも同じではありません。
ところで、「enum fruit myFruit」と言わなければならないことを避けるために、typedef で enum を避けることができます。「typedef enum fruit fruit;」を使用するだけです。専用線で。これで、enum を前に付けずに「fruit myFruit」と言うことができます。多くの場合、列挙型が定義されているときに直接行われます。
typedef enum fruit { apple = 0, banana, cherry, peach, grape } fruit;
fruit myFruit;
欠点は、果物が列挙型であることをもはや知らないことです。それはオブジェクト、構造体、またはその他のものである可能性があります。私は通常、これらのタイプの typedef を避けます。enum の場合は enum を前に、構造体の場合は struct を前に記述します (見栄えが良いので、ここではそれらを使用します)。
文字列値を取得できません。実行時には、列挙は単なる数値です。つまり、列挙の種類がわからない場合は不可能です (0 はリンゴかもしれませんが、別の列挙セットの別のものである可能性もあります)。ただし、それが果物であることがわかっている場合は、それを実行する関数を簡単に作成できます。プリプロセッサはあなたの友達です:-)
typedef enum fruit {
apple = 0,
banana,
cherry,
peach,
grape
} fruit;
#define STR_CASE(x) case x: return #x
const char * enum_fruit_to_string(fruit f) {
switch (f) {
STR_CASE(apple); STR_CASE(banana); STR_CASE(cherry);
STR_CASE(peach); STR_CASE(grape);
}
return NULL;
}
#undef STR_CASE
static void testCall(fruit f) {
// I have no idea what fruit will be passed to me, but I know it is
// a fruit and I want to print the name at runtime
printf("I got called with fruit %s\n", enum_fruit_to_string(f));
}
int main(int argc, char ** argv) {
printf("%s\n", enum_fruit_to_string(banana));
fruit myFruit = cherry;
myFruit++; // myFruit is now peach
printf("%s\n", enum_fruit_to_string(myFruit));
// I can also pass an enumeration to a function
testCall(grape);
return 0;
}
出力:
banana
peach
I got called with fruit grape
これはまさにあなたが望んでいたものですか、それとも私はここで完全に間違った方向に進んでいますか?