C言語初学者です
列挙型の変数が一体どんなものなのかよくわかりません
列挙型の変数を宣言して、その変数に代入するとき、
enum goo{
zero = 0,
one,
two
};
enum goo num = zero;
のような感じで書いてあるのですが、この変数の宣言を
int num = 0;
としても同じだし、また、列挙型の変数への代入は列挙型の定数(zero, one...)を使用せず、
enum goo num = 10;
と書いても、実際は
int num = 10;
と変わらないと考えてよいのでしょうか?
つまり結局、列挙型の変数はint型変数と変わりないということでしょうか?
No.7ベストアンサー
- 回答日時:
う〜む。
まぁ、極端な話、Cの「型」ってのは突き詰めると、あってないようなモノで、全部数値に落ち着いちゃうからそっちから考えると混乱するとは思うよ。
そうじゃなくって、「用法」から考えた方がベターなんじゃないのかな。つまり、ある局面に於いて、ある「機能」は、「便利だから」存在する、と言う考え方だ。
個人的にはCは得意じゃないんだけど、ちと説明してみようか。
プログラミングをやってると、何らかの「名前」だけを使いたい、って場合が多いんだ。
そういう「名前だけを」使えるプログラミング言語もあるんだけど、一般にそういうのは許されないケースの方が多い。
例えばオセロを考える。盤面の「状態」は、黒、白、空、盤外の4つ。直接に黒、白、空、盤外と言う「名前」を使ってプログラムを書きたいんだけど、そいつは許されないわけだよな。
通常そういう時は変数を用意して、
int black = 0;
int white = 1;
int empty = 2;
int outer = 3;
とか書いて対応するわけだが・・・要はこんなん書くのがメンドいんだよ(笑)。出来ればそのままblack、white、empty、outerと言う「名称」を使いたい。
そういう「名称だけ使いたい」時に使うのが列挙体なんだ。
そして、上の例の時、blackには0が入ってて、whiteには1が入ってて・・・とか言うのも「たまたま」だ。別にblackが3でwhileが0で・・・でも構わないわけでしょ?要は「数値は区別の為に使われてるんであって、数値そのものには大した意味がない」。言い換えると「その数にせなアカン」と言う理論的な根拠は全くないわけだ(そしてwhite + empty = outerって言う「計算が成り立つ」なんつーのもオセロ、と言うゲームでは意味がない)。
そういう「数値自体に特に意味がない」時、プログラムする側が、何らかのトリッキーな事を考えてないのなら、「blackに何の数を代入すべきだ・・・?」とか熟考するのは無駄でしょ(笑)。だって目的は「識別の為」だけであって、使われてる数値自体には特に意味がねぇんだから。
この辺の数値選び、はコンパイラやインタプリタに面倒見てほしい。余計な事は何も考えたくないからだ。つまり、「自動で名前に数値を振り分けてくれれば便利なのに」を体現したのが「列挙体」だ。
列挙体、ってのは変な日本語だけど、英語では元々Enumerated Typeと呼ぶ。enumerateってのは「数え上げる」って意味なの。あるいは「数値を振り分ける」とかそういうニュアンス。
んで、他の人は「整数に名前を付けるもの」とか書いてるけど、モダンなプログラミングの観点は逆で、「名前に整数を振り分ける」って考えた方が分かりやすいと思う。enumerateされてるのは「名前」であって、数値じゃないし、上にも書いてきたけど、ここで言う「数値」、つまり整数はidナンバー以上の意味はないんだ。
んで、繰り返すけど、個人的にはCは得意じゃないんだけど、「列挙体の使用方法」で言うと、恐らくユーザー定義型と組み合わせた例の方が多いんじゃない?多分。
例えば上のオセロのようなケースだと、列挙体定義時にtypedefと組み合わせて、
typedef enum piece {black, white, empty, outer} piece_t;
と記述して「piece_t型」っちゅう「新しい型」を定義する。typedefによりユーザー定義型を導入する事で、プログラムはより「意味」が「明確」になる。ここにあるblack、white、empty、outerと言う「名前」は、既に設定された「整数」から意味が乖離している。
でもそれでいい。高級言語の存在意義は「人間にとって意味が見出しやすい」であり、「意味のある名前を使える」ってのは何にも増して代えがたいんだ。「blackは0だったから・・・」って覚えておく必要はなく、ここでは既にblackはpiece_t型のblack以上の意味はない。また、もし「数値を重要視して数値だけでプログラムを書きたい」んなら、高級言語なんかは使わずにマシン語でプログラムを書けばいいだろう、って話になるだろうしね。
繰り返すけど、数値を使わず、「名前によって人にとっての意味を明確化する」ってのは高級言語の重要なコンセプトなんだ。
なお、typedefと列挙型の組み合わせは、例えば素の列挙体で、
enum eng {foo, bar, baz};
enum jap{hoge, fuga, piyo};
とした場合、foo == hogeなんつー判定が出来るトコを
typedef enum eng {foo, bar, baz} eng_t;
typedef enum jap{hoge, fuga, piyo} jap_t;
ではfoo == hogeの判定を許さない・・・いや、言い過ぎだな。コンパイルは通るかもしんないけど、Warningが出る処理系が多いだろう。「ユーザー定義型」として新しい型、eng_t型とjap_t型を設定した以上、fooに設定された0とhogeに設定された0は「意味が違う」事となる。これがバグを未然に防ぐ事にも繋がるだろう。
分かったかしらん?実態は突き詰めると整数型だろ、とか言うのは正しいんだけど、そうじゃなくって「プログラマが意味ある名前をそのまま使いたい」(そして設定された数値自体に意味はさしてない)場合に利用するのが列挙体の存在意義なんだ。
※1: ちなみに、挙げられたプログラム例の
enum number{
zero,
one,
two
};
enum number n; //列挙型変数の宣言
ってのは多分冗長な定義法なんじゃないか・・・・・・Cの仕様上、
enum number{
zero,
one,
two
} n; // n は列挙型変数の宣言
と記述すれば即刻nはenum number型の変数と認識される筈だ。
※2: 実の事を言うと、昨今のモダンなプログラミング言語だと、列挙体自体が存在しない言語の方が多いんじゃないか・・・列挙体が「ある」のはC言語系の例えばJava、あるいは既に古い言語になっちまったPascal、とかだけど、PythonやRubyなんかの言語だと存在しない(Rubyの列挙型ってのはここでの列挙体とは意味が違うし)。
だから、モダンな言語デザイナー達自身が、「あんま列挙体使わんかったな・・・」とか思ってる、って事かもしんない(笑)。使わんかったから自身の言語からその機能を削除した、とか(笑)。
そう考えると、あるいは今後別のプログラミング言語へ移動する、って事を視野に入れると、そんなに頑張って「列挙体を使いこなせるようにならなければ!」って程じゃないのかもしんない(笑)。
No.6
- 回答日時:
仕様のこまかいところはともかく、
C言語においては
・「列挙型」は整数に名前を付けるもの。マクロに近い
・「列挙型変数」は「整数型変数」と同じもの
(ここでの「整数」はintとは限らない)
と考えといていいと思う。
> そして回答から言うに(略)
混同しているようですが
その例題だと
zero,one 等は「enum number列挙型の値」であって「列挙型変数」ではありません。
列挙型変数と呼べるのは「enum number n;」で宣言した変数nです。
なお、C++では判定が厳しくなっており、
enum goo num = 10;
等はできなくなっています。
No.4
- 回答日時:
まずこの質問文の例は, ぶっちゃけ「enum の意義をないがしろにしている」といっていいような気がする. 最大限好意的に解釈しても「粗悪」. #1 の例が一般的じゃないかなぁ....
enum の存在意義としては
「ただの int の数値」に「意味のある名前」を付ける
ことにあると思う. 関数の
「ただの処理の流れ」に「意味のある名前」を付ける
機能と対比できるかもしれない.
なお「必ず int」というわけではなく, char や unsigned int になる可能性もある.
しかし「equal number」とか, いったい誰がいいだしたのだか....
No.3
- 回答日時:
全く違いますね。
enum goo num = 10;の意味は num という文字列が 10という文字列と等価であると言うことです。コンパイラ(プリコンパイラか1パス)がnumという文字列を10に置き換える事になります。
int num = 10;はnumという関数エリアを確保してそこに10を代入します。
ソースリストを見たときに数の意味をわかりやすくするために意味を持った単語に置き換えるのが効用ですがC,C#等ではコメントで表示すれば済みますから却って解りにくくなりますね。
enum goo numではint変数にでもdouble変数にでもerror,warnigにならずに代入できます。
enumはequal numberの略ですね。
No.2
- 回答日時:
enum 型は読み込み専用で、値の更新はできません
可読性の観点から存在するといってもいい
enum goo num = 10;
const num = 10;
かな
昔(30年)前は、K&RのCのガチガチの人は、enumつかわなかったな
そしてソースが見にくいし、関数のプロトタイプ宣言しないので
関数がint引数、int戻りに仮定されるので困ったことが多かった
No.1
- 回答日時:
同じなんですが。
enumを使うことで数字に意味を持たせることができます。
例えば
enum week{
Mon = 0,
Tue,
Wed,
Thu,
Fri,
Sat,
Sun
};
のようにします。
そうすると、
if(day == 0){
printf("月曜日\n");
}
よりも
if(day == Mon){
printf("月曜日\n");
}
のほうがわかりやすくなります。
あなたが個人で作ったプログラムならenumを使わなくても結構です。
ただ、他人が読む可能性があるソースコードの場合、enumを使ったほうがわかりやすくなります。
10年前のソースコードを読んで、「この3ってなんだっけ?」となることがよくあります。
この様な数字をマジックナンバーと言います。
enumを使えばマジックナンバーを使わずに済みます。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# C言語初心者 構造体 課題について 2 2023/03/10 19:48
- C言語・C++・C# C言語初心者 ポインタについて、お助けください、、 2 2023/03/15 23:50
- C言語・C++・C# c言語 int temp = 0; if(isdigit(arr[i])){ temp=arr[i] 2 2022/03/27 01:44
- C言語・C++・C# C言語プログラム変更 2 2022/12/21 15:03
- PHP カラーミーショップのSmartyでの文字列抜き出し 2 2022/05/06 11:51
- C言語・C++・C# ポインタの宣言方法 1 2023/10/26 20:32
- C言語・C++・C# C言語の課題が出たのですが自力でやっても分かりませんでした。 要素数がnであるint型の配列v2の並 3 2022/11/19 17:41
- PHP 配列の値の更新方法について 1 2022/08/05 09:49
- C言語・C++・C# C言語について コマンドラインで >変数 12.00 (char型) と、小数点付きの値を共用体に渡 1 2022/04/22 16:56
- C言語・C++・C# このプログラミング誰か教えてくれませんか 1 2022/06/02 15:27
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・【大喜利】【投稿~11/12】 急に朝起こしてきた母親に言われた一言とは?
- ・好きな和訳タイトルを教えてください
- ・うちのカレーにはこれが入ってる!って食材ありますか?
- ・好きな「お肉」は?
- ・あなたは何にトキメキますか?
- ・おすすめのモーニング・朝食メニューを教えて!
- ・「覚え間違い」を教えてください!
- ・とっておきの手土産を教えて
- ・「平成」を感じるもの
- ・秘密基地、どこに作った?
- ・【お題】NEW演歌
- ・カンパ〜イ!←最初の1杯目、なに頼む?
- ・一回も披露したことのない豆知識
- ・これ何て呼びますか
- ・チョコミントアイス
- ・初めて自分の家と他人の家が違う、と意識した時
- ・「これはヤバかったな」という遅刻エピソード
- ・これ何て呼びますか Part2
- ・許せない心理テスト
- ・この人頭いいなと思ったエピソード
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・あなたの習慣について教えてください!!
- ・ハマっている「お菓子」を教えて!
- ・高校三年生の合唱祭で何を歌いましたか?
- ・【大喜利】【投稿~11/1】 存在しそうで存在しないモノマネ芸人の名前を教えてください
- ・好きなおでんの具材ドラフト会議しましょう
- ・餃子を食べるとき、何をつけますか?
- ・あなたの「必」の書き順を教えてください
- ・ギリギリ行けるお一人様のライン
- ・10代と話して驚いたこと
- ・家の中でのこだわりスペースはどこですか?
- ・つい集めてしまうものはなんですか?
- ・自分のセンスや笑いの好みに影響を受けた作品を教えて
- ・【お題】引っかけ問題(締め切り10月27日(日)23時)
- ・大人になっても苦手な食べ物、ありますか?
- ・14歳の自分に衝撃の事実を告げてください
- ・架空の映画のネタバレレビュー
- ・「お昼の放送」の思い出
- ・昨日見た夢を教えて下さい
- ・ちょっと先の未来クイズ第4問
- ・【大喜利】【投稿~10/21(月)】買ったばかりの自転車を分解してひと言
- ・メモのコツを教えてください!
- ・CDの保有枚数を教えてください
- ・ホテルを選ぶとき、これだけは譲れない条件TOP3は?
- ・家・車以外で、人生で一番奮発した買い物
- ・人生最悪の忘れ物
- ・【コナン30周年】嘘でしょ!?と思った○○周年を教えて【ハルヒ20周年】
- ・あなたの習慣について教えてください!!
- ・都道府県穴埋めゲーム
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
VBAでダブルコーテーション入り...
-
エラーの意味は? Lvalue req...
-
processing エラーで、 "cannot...
-
C言語 アロー演算子について質...
-
jsp~jspにhiddenを使って変数...
-
EXCEL/VBA 変数の値をクリップ...
-
i++と++i ってどう違うのですか?
-
インクリメント演算子の前置(+...
-
【VBA】複合代入演算子
-
変数にオフセットが付いている...
-
プログラミングで変数と関数の...
-
C言語 列挙型(enum型)変数について
-
JavaScriptをURLから直接実行し...
-
int→unsigned int キャスト
-
[VBS]変数を定数に変換する方法...
-
整数xxxが大き過ぎますというエ...
-
C言語 初心者です。
-
C言語 exitの使い方
-
フォームを開くときに、コンボ...
-
COLUMN(1:1)の意味を教え...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
エラーの意味は? Lvalue req...
-
VBAでダブルコーテーション入り...
-
テキストボックスの値を変数に...
-
processing エラーで、 "cannot...
-
Variant型で宣言してるのにEmpt...
-
EXCEL/VBA 変数の値をクリップ...
-
[VBS]変数を定数に変換する方法...
-
C言語 アロー演算子について質...
-
jsp~jspにhiddenを使って変数...
-
整数xxxが大き過ぎますというエ...
-
プログラミングで変数と関数の...
-
変数にオフセットが付いている...
-
ExcelのVBAでをA列に第0〜19項...
-
「%」を使って、偶数か奇数かを...
-
【VBA】複合代入演算子
-
無名関数のメリットがよくわか...
-
gridViewの行選択解除
-
VBA 1行で複数の代入を行った...
-
コマンドプロンプト バッチ|結...
-
stdpicture型の変数に、、
おすすめ情報
例示のコードですが、参考本から抜き出してきたものです
そんな使い方をされて本気で意味が分からなかった結果ここにたどり着いたので、粗悪より悪い言葉使ってもいいと思います
enum number{
zero,
one,
two
};
enum number n; //列挙型変数の宣言
n = two;
printf("%d\n",n);
という風に使っていて、まったく意図がわかりませんでした
それならintでいいじゃん...しかも使うのprintfではなく、True, Falseじゃない?と思いました
そして回答から言うに、その本で書かれている「列挙型変数」とは、後付けで編集可能な列挙型のような立ち位置で、int変数などとの違いは、アドレスから引っ張り出して計算しているか、シンボルとして直接計算しているかで、表面的にあまり変わりはないと理解してよいでしょうか
たくさんのご回答ありがとうございます
もしかしたら自分は沼に片足突っ込んでいたのかもしれませんね...
しかしまず、typedef enum num{} NUMBER; NUMBER a が int a と表面的には同じということを知ることができ、加えて列挙型の深堀した解説もお聞きできてよかったです
自分は、まだC言語の学習を標準入出力と処理制御くらいまでしか進んでおらず、作ったトイプログラムと言えばうるう年と素数の判定くらいなので、今の段階では列挙型自体を使えればよいという認識で、学習を進めていきたいと思います
改めましてご回答ありがとうございました!