「C言語/データ型と変数の高度な話題」の版間の差分

削除された内容 追加された内容
Ef3 (トーク | 投稿記録)
→‎enum: nDay_of_the_Week の意味
タグ: 2017年版ソースエディター
Ef3 (トーク | 投稿記録)
{{Nav}}
タグ: 2017年版ソースエディター
651 行
}
</syntaxhighlight>
 
実行結果
<pre>
0: 日曜日
1: 月曜日
2: 火曜日
3: 水曜日
4: 木曜日
5: 金曜日
6: 土曜日
</pre>
 
enumの各要素には、自動的に要素の宣言順に0,1,2,・・・の値が割り当てられます。なので上記の実行例の「0」や「1」なども、enumの各要素に割り当てられた値を表示したものに過ぎません。
 
enumの各要素には割り当てられる値は通常は整数値なので原理上はint型などとの計算や代入が可能ですが、ただし列挙型は仕様があいまいでありコンパイラの実装に依存するので、あまりenumの値を計算しないほうが良く、enum値には加算乗除などは行わずにそのまま表示するなどするのが安全であろう。
 
列挙子の名前が <code>dw</code> で始まるのはタグ <code>'''D'''ay_of_the_'''W'''eek</code> の列挙子であることを示し、最後の列挙し <code>nDay_of_the_Week</code> 列挙子の総数で Number of <code>Day_of_the_Week</code> のつもり。列挙型の変数、<code>dw</code> はもちろん <code>enum '''D'''ay_of_the_'''W'''eek</code> 型であることを示しています。
672 ⟶ 657行目:
 
[[C++]]のコードとしてコンパイルすると、dw++ がエラーになります<ref>[https://paiza.io/projects/idW8CifxFGXZ5bG1sdRdWA?language=c static_cast を使えば]、<syntaxhighlight lang="cpp" inline>dw = static_cast<Day_of_the_Week>(dw + 1)</syntaxhighlight>コンパイルできますが、<code>static_cast</code>は、コンパイラーの型チェックを骨抜きにしてしまうので、乱用は避けましょう(operator ++ をオーバーロードするにしても、その中で static_cast が必要)。</ref>。
 
 
enum の宣言時に同時にenum変数を宣言することも可能であり、下記コードのように宣言できる。
<syntaxhighlight lang="C" highlight=18 line>
#include <stdio.h>
 
enum Day_of_the_Week {
dwSUNDAY,
dwMONDAY,
dwTUESDAY,
dwWEDNESDAY,
dwTHURSDAY,
dwFRIDAY,
dwSATURDAY,
nDay_of_the_Week,
} dw; // enum の最後で変数を宣言
 
int main(void) {
const char *names[nDay_of_the_Week] = {
"日曜日", "月曜日", "火曜日", "水曜日", "木曜日", "金曜日", "土曜日",
};
for (dw = dwSUNDAY; dw < nDay_of_the_Week; dw++) { // 変数宣言はしてないので dw に型は不要になる
printf("%i: %s\n", dw, names[dw]);
}
}
</syntaxhighlight>
 
;ネストは無い
enum のネストは用意されていない。標準C言語でなくC++の話題になるが、仮にC++のclass機能の<code>{ }</code>ブロック内にenumのブロックを入れてみても、見た目はネストっぽくなるが、見た目だけに過ぎず、そうしたところで外側のclassにenumの機能は無い。
 
あるいは別の方法を試みようとして、たとえば外側をenumブロック、その内側に構造体ブロックを入れても、構造体の定義の際にメンバに int 型などを定義しなければいけなくなるので、コンパイル不能で動作しないか、もし仮にコンパイルできたとしても意図しない動作になりかねないので危険であろう。
 
 
 
;応用例
switch文と組み合わせることで、switch文を使う際のラベルの定数を考える手間を省略できます。
 
<syntaxhighlight lang="C" highlight=18 line>
#include <stdio.h>
 
int main(void) {
// 商品リスト
struct product_list {
char name[32]; // 商品名
int price; // 価格
};
 
struct product_list drinks[10]; // 構造体配列の宣言
 
// ここにenumあり
enum materialType {
Milk,
OrangeJuice,
vegi,
} varType;
 
for (int i = 0; i <= 2; i = i + 1) {
switch (i) {
case Milk: drinks[i] = (struct product_list){ "牛乳", 120 }; break; // case のラベルでenum変数の活用
case OrangeJuice: drinks[i] = (struct product_list){ "オレンジジュース", 240 }; break; // 以下、同様
case vegi: drinks[i] = (struct product_list){ "野菜ジュース", 190 }; break;
default : break;
}
}
 
for (int temp = 0; temp <= 2; temp = temp + 1) {
printf("商品『%s』の値段は%d 円\n", drinks[temp].name, drinks[temp].price);
}
}
 
</syntaxhighlight>
 
実行結果
<pre>
商品『牛乳』の値段は120 円
商品『オレンジジュース』の値段は240 円
商品『野菜ジュース』の値段は190 円
</pre>
 
===タグ===
1,056 ⟶ 963行目:
* 国際標準化機構/国際電気標準会議 [https://www.iso.org/obp/ui/#iso:std:iso-iec:9899:ed-4:v1:en ISO/IEC 9899:2018(en) Information technology — Programming languages — C](2018-07-05)
* 日本工業標準調査会(当時、現:日本産業標準調査会)『JISX3010 プログラム言語C』2003年12月20日改正
 
{{Nav}}
 
[[Category:C言語|てえたかたとへんすう]]