カンパ〜イ!←最初の1杯目、なに頼む?

C++だけでなく、Cでも同様なのだと思うのですが、下記の(1)、(2)の違い
がよくわからず、どなたかにご教授いただければと思っています。

(1)
struct{
  (略)
}BBB;

(2)
typedef struct{
  (略)
}BBB;

(2)が下記((2)')のようになるんであれば、AAAという名前の構造体を
BBBという名前で定義しているという事で理解できるんですが、
(2)のようにしている意図が理解できません。
(typedefの記述は必要なんでしょうか?)
すでに動いているシステムなので、問題ないのは明らかなんですが。

(2)'
typedef struct AAA{
  (略)
}BBB;

A 回答 (4件)

> すみません。

BBBとAAAの記述が反対で、

何か誤解があるようです。

typedef struct{
  (略)
}BBB;

の型は struct { (略) } であり、

typedef struct BBB{
  (略)
}AAA;

の型は struct BBB { (略) } です。
両者は別の型ですし、タグがAAAになってもそれは同じことです。

> ★これは、typedefの記述が無くても同様ではないんでしょうか?(下記(3))

typedefがなければ、それは型定義ではなくオブジェクトの宣言になります。

> typedefが必要なのかが理解できていません。

最初に書いたように、タグ名がない構造体は、たとえ内容が全く同じでも出現するたびに別の型になります。したがって、タグが無い場合にはtypedef名を定義しておかない限り、その型を再度指定する手段がなくなります。
(GCCのようにtypeof演算子がある場合や、C++でテンプレートを用いた場合は別です)
    • good
    • 0
この回答へのお礼

混乱してたようです^^;
再度の対応をいただき、ありがとうございます。
回答内容を良く整理して、これ以上混乱しないようにしたい
と思っております。

お礼日時:2007/11/13 15:46

>typedefの役割について


質問の例はわかり難いので、例を変えて説明します。
----------------------------------------------
//(a)
struct {
  int hoge;
} aaa;

//(b)
struct BBB{
  int hoge;
} bbb;

//(c)
typedef struct {
  int hoge;
} ccc;

//(d)
typedef struct DDD{
  int hoge;
} ddd;

void test1(void){
  aaa.hoge = 10;
  bbb.hoge = 10;
  ccc.hoge = 10; // NG (1)
  ddd.hoge = 10; // NG (2)
}

void test2(void){
  struct {
    int hoge;
  }aaa2;
  aaa2 = aaa; // NG (3)
  
  struct BBB bbb2;
  bbb = bbb2;

  ccc ccc1;
  ccc ccc2;
  ccc1 = ccc2;
  
  ddd ddd1;
  struct DDD ddd2;
  ddd1 = ddd2;
}
----------------------------------------------
// NG の行はコンパイルエラーになると思いますが、
理由は分かりますか?

(a)は変数の宣言。
(b)は型の宣言と、変数の宣言。
(c)は別名の宣言。
(d)は型の宣言と、別名の宣言。

test1() は、メンバへの代入を試みています。
NG (1) と (2) のエラーは、ccc dddは変数では無く、
型の別名ですので、そのまま変数の様には扱えません。

test2() は、同じ型の変数を用意して構造体の代入を試みています。
NG (3) は、aaa と同じように宣言していますが、
別の型として扱われるので、エラーになります。

また、下記の2行を比べてください。
同じ型の構造体の変数を宣言していますが、
typedefで定義した別名を使う方が、簡素になります。

ddd ddd1;
struct DDD ddd2;

typedefの主な用途はこの点だと思います。

#専門家ではないので、細かい専門用語の間違いなどはご容赦下さい。
#サンプルソースはレイアウトの為に全角スペースを入れています。
    • good
    • 0
この回答へのお礼

なるほど^^
例まで書いていただき、ありがとうございます。
自分の理解が足りていない部分が回答内容から
良くわかりました。

お礼日時:2007/11/13 15:48

(2)と(2)'では型が異なります。


タグ名のない構造体は、内容が全く同じであっても、その定義が現れるたびに別の型であると認識されます。もちろん、内容が全く同じタグ名付きの構造体とは別の型です。

(2)では、その型を扱う場合には常にBBBという名前を使うことを意図しており、タグ名前空間を汚染していません。
それに対して、(2)'では、AAAという名前が、実際に使われるかどうかにかかわらず、タグ名前空間を汚染しています。

C++では若干事情が異なります。C++ではタグ名前空間というものがありません。したがって、使用しないタグ名を付けると、一般的な識別子とぶつかる可能性が出てきます。
    • good
    • 0
この回答へのお礼

回答ありがとうございます。

1つ質問を追加(下記★)させていただきましたので、
すみませんが、回答いただければうれしいです。

>(2)と(2)'では型が異なります。
そうですね^^;
すみません。BBBとAAAの記述が反対で、
-------------------------------------------
typedef struct BBB{
  (略)
}AAA;

BBBという名前の構造体をAAAという名前で定義
-------------------------------------------
↑の誤りでした。失礼しました。

>(2)では、その型を扱う場合には常にBBBという名前を使うことを意図しており、タグ名前空間を汚染していません。
★これは、typedefの記述が無くても同様ではないんでしょうか?(下記(3))
typedefが必要なのかが理解できていません。

(3)
struct{
  (略)
}BBB;

お礼日時:2007/11/13 12:41

2は2'の省略型


typedefで名前つけてるので構造体名を省略したのでしょう
    • good
    • 0
この回答へのお礼

早急な回答、ありがとうございました。

お礼日時:2007/11/13 12:42

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!


おすすめ情報