構造体 typedef
構造体 typedef
typedefがいまいちよく理解できません。typedefを使うとstructを一々付けなくても済むとかいてあるのですが、よけい分かりにくくなってる気がします。
struct seiseki seito{
int no;
char nmae[20];
};
int main(void){
struct seiseki seito;
}
これが基本的な構造体ですよね。それでtypedefを使って宣言すると、
typedef struct seiseki{
int no;
char name[10];
}seiseki;
int main(void){
seiseki seito;
}
要するに、main()の中でstructを省略できるってこと??
struct seiseki seito{
int no;
char nmae[20];
};
int main(void){
struct seiseki seito;
}
これが基本的な構造体ですよね。それでtypedefを使って宣言すると、
typedef struct seiseki{
int no;
char name[10];
}seiseki;
int main(void){
seiseki seito;
}
要するに、main()の中でstructを省略できるってこと??
Re:構造体 typedef
そういう事です。
ちなみに、構造体の名前とは違う名前を付ける事も可能です。分かりにくくなるので、あまりやらない方が良いでしょうけど…(;^_^A
この機能、構造体を使う場所が少ない場合には有り難みが薄いでしょうが、多くなってくると便利に感じると思いますよ。
ちなみに、構造体の名前とは違う名前を付ける事も可能です。分かりにくくなるので、あまりやらない方が良いでしょうけど…(;^_^A
この機能、構造体を使う場所が少ない場合には有り難みが薄いでしょうが、多くなってくると便利に感じると思いますよ。
Re:構造体 typedef
structを書かなくてよくなるってことですね。
ちなみに
ちなみに
typedef struct seiseki{ int no; char name[10]; }seiseki; int main(void){ seiseki seito; }こうではなく、普通
typedef struct{ int no; char name[10]; }seiseki_t; int main(void){ seiseki_t seito; }こう書きます。型の名前を変数名と混合しないように気をつけましょう。
Re:構造体 typedef
typedef struct seiseki{ int no; char name[10]; }seiseki;あら、これはこれで正しいんではなかったですか?
最初のseisekiが構造体名で、最後のseisekiが置き換えられる名前っていう意味だと思ってました(;^_^A
私の中では#defineの構造体版だと解釈してたもので…?
Re:構造体 typedef
> あら、これはこれで正しいんではなかったですか? はい、正しいです。むしろ、こちらの書き方の方がよいと思います。 自己参照型構造体を定義する場合、こちらの書き方でないとまずいからです。 > 私の中では#defineの構造体版だと解釈してたもので…? #define と typedef とは、別の概念です。 #define : 単なる字句の置き換え typedef : ある型の別名を作るイメージ
Re:構造体 typedef
>私の中では#defineの構造体版だと解釈してたもので
boxさんが書かれているとおり、役割が全く異なりますし。
#defineはコンパイル処理の前半で行われ、文字通り「文字の置き換え」です。
構文に関係なくマッチすれば置き換えるので、利点もありますが、逆に俗に言う副作用が生まれたりします。
typedefは反対にコンパイル処理の後半で行われ、型に対して名前を定義します。
型であれば何でも名前を付けられるので、「charへのポインターを返す関数へのポインターを返す関数へのポインターN個からなる配列」とかでも定義できます。
昔C言語で行列計算をしていた頃は「16個からなる float/doubleの配列」を MATRIX型として定義して扱っていました。
このあたりのニュアンスの違いが分かってくると、C言語の奥の深さが見えてくるかと思います。
>はい、正しいです。むしろ、こちらの書き方の方がよいと思います。
>自己参照型構造体を定義する場合、こちらの書き方でないとまずいからです。
私も boxさんに1票。
前方参照できた方が何かと便利なんで。
boxさんが書かれているとおり、役割が全く異なりますし。
#defineはコンパイル処理の前半で行われ、文字通り「文字の置き換え」です。
構文に関係なくマッチすれば置き換えるので、利点もありますが、逆に俗に言う副作用が生まれたりします。
typedefは反対にコンパイル処理の後半で行われ、型に対して名前を定義します。
型であれば何でも名前を付けられるので、「charへのポインターを返す関数へのポインターを返す関数へのポインターN個からなる配列」とかでも定義できます。
昔C言語で行列計算をしていた頃は「16個からなる float/doubleの配列」を MATRIX型として定義して扱っていました。
このあたりのニュアンスの違いが分かってくると、C言語の奥の深さが見えてくるかと思います。
>はい、正しいです。むしろ、こちらの書き方の方がよいと思います。
>自己参照型構造体を定義する場合、こちらの書き方でないとまずいからです。
私も boxさんに1票。
前方参照できた方が何かと便利なんで。
Re:構造体 typedef
管理人さんが言いたかったのは、
XXX_t と後ろに _t をつけて、構造体であるということを明確にするのが一般的だよ
ということだと思います。
多分・・・
XXX_t と後ろに _t をつけて、構造体であるということを明確にするのが一般的だよ
ということだと思います。
多分・・・
Re:構造体 typedef
そらさん,ありがとうございます^^;
私が言いたかったのはそういうことだったのですが,最初からすっかり指摘された点を忘れていました^^;
すみません・・。
いつも自分の好きな使い方だけしてたんじゃだめですね~><;
私が言いたかったのはそういうことだったのですが,最初からすっかり指摘された点を忘れていました^^;
すみません・・。
いつも自分の好きな使い方だけしてたんじゃだめですね~><;
Re:構造体 typedef
typdef 一般の話になれば、抽象的な型定義のためには必須というところでしょうか。
例えば、ファイル操作でお世話になる、fopen() の返値は、FILE * 型ですが、そもそも、FILE 型自体が、ファイル操作に関連したデータをあつめた構造体です。
ただ、具体的にどんなデータが必要かは、実行環境により、OSにより様々です。
それでも、
FILE *fopen(const char *filename, const char *mode);
という一般形で関数を定義するためには、これを、FILE * 型という、抽象的な型を導入する必要があったわけです。
具体的には、実行環境に適切な形で、typedef されています。
しかも、FILE * は、「処理系で適切な形」であって、必ずしも、構造体である必要はありません。
ですから、構造体かもしれないし、単純型かも知れないし、といった可能性を統一的に(しかも安全に)覆い隠して、抽象的な FILE 型を提供するのには、 typedef が必要だったということになります。
また、size_t 型も、sizeof 演算子の返値として定義されています。
これも、処理系に応じて、適切なサイズの(多分)int 型に typedef されています。
ちょっと考えると、size_t など持ち込まなくても、int で良いような気がしますが、多分、int ではまかないきれないサイズの配列や構造体も意識されたのでしょう。
例えば、ファイル操作でお世話になる、fopen() の返値は、FILE * 型ですが、そもそも、FILE 型自体が、ファイル操作に関連したデータをあつめた構造体です。
ただ、具体的にどんなデータが必要かは、実行環境により、OSにより様々です。
それでも、
FILE *fopen(const char *filename, const char *mode);
という一般形で関数を定義するためには、これを、FILE * 型という、抽象的な型を導入する必要があったわけです。
具体的には、実行環境に適切な形で、typedef されています。
しかも、FILE * は、「処理系で適切な形」であって、必ずしも、構造体である必要はありません。
ですから、構造体かもしれないし、単純型かも知れないし、といった可能性を統一的に(しかも安全に)覆い隠して、抽象的な FILE 型を提供するのには、 typedef が必要だったということになります。
また、size_t 型も、sizeof 演算子の返値として定義されています。
これも、処理系に応じて、適切なサイズの(多分)int 型に typedef されています。
ちょっと考えると、size_t など持ち込まなくても、int で良いような気がしますが、多分、int ではまかないきれないサイズの配列や構造体も意識されたのでしょう。
自己参照型構造体
今までの話の流れとは少し違いますが気になったので書き込みさせてください。
>Name: box Date: 2007/03/19(月) 09:43
>
>はい、正しいです。むしろ、こちらの書き方の方がよいと思います。
>自己参照型構造体を定義する場合、こちらの書き方でないとまずいからです。
とありますが、どうして自己参照型の構造体では上記のような書き方をしないといけない
のか?
が分かりません。
>Name: バグ Date: 2007/03/19(月) 07:51 > typedef struct seiseki{ > int no; > char name[10]; >}seiseki;のコードに対して、
>Name: box Date: 2007/03/19(月) 09:43
>
>はい、正しいです。むしろ、こちらの書き方の方がよいと思います。
>自己参照型構造体を定義する場合、こちらの書き方でないとまずいからです。
とありますが、どうして自己参照型の構造体では上記のような書き方をしないといけない
のか?
が分かりません。
typedef struct seiseki{ int no; char name[10]; struct seiseki * p_next; }seiseki_t;なぜこのような書き方はだめなのでしょうか?
Re:自己参照型構造体
>size_t など持ち込まなくても、int で良いような気がしますが、
>多分、int ではまかないきれないサイズの配列や構造体も意識されたのでしょう。
ですね。
私が前に見たことある処理系では
int 4バイト
long 8バイト
void * 8バイト
size_t 8バイト
てなのがありました。
メンバ関数へのポインタのサイズなんて恐ろしくて調べていません(w
>多分、int ではまかないきれないサイズの配列や構造体も意識されたのでしょう。
ですね。
私が前に見たことある処理系では
int 4バイト
long 8バイト
void * 8バイト
size_t 8バイト
てなのがありました。
メンバ関数へのポインタのサイズなんて恐ろしくて調べていません(w
Re:自己参照型構造体
> >自己参照型構造体を定義する場合、こちらの書き方でないとまずいからです。 ここで言っていた「こちらの書き方」とは、「構造体タグ名を書く書き方」のことでした。 バグさんのくだんの投稿における構造体定義は、自己参照型ではありません。 自己参照型でない構造体の場合、構造体タグ名を省略できます。書いてもかまいません。 自己参照型の構造体の場合、構造体タグ名が必要です。省略できません。 というわけで、自己参照型かどうかにかかわらず、いつでも構造体タグ名を書いておけば 間違いがない、ということであります。
Re:自己参照型構造体
書き込みありがとうございます。
構造体のタグ名の部分を見落としていて、
seiseki とseiseki_tの部分しか見ていませんでした。
ありがとうございます。
構造体のタグ名の部分を見落としていて、
seiseki とseiseki_tの部分しか見ていませんでした。
ありがとうございます。