web-dev-qa-db-ja.com

ヘッダーファイルで構造体を使用する "不明なタイプ"エラー

KubuntuでKdevelopを使用しています。 datasetup.hファイルで構造を宣言しました。

#ifndef A_H
#define A_H

struct georeg_val {

    int p;
    double h;
    double hfov;
    double vfov;
};

#endif

Main.cファイルで使用すると

int main()
{
    georeg_val gval;

    read_data(gval); //this is in a .cpp file

}

次のエラーが発生します。

georeg_chain.c:7:3:エラー:不明なタイプ名 'georeg_val'

(これはgeoreg_val gval;行)

誰かがこのエラーの解決を手伝ってくれるとありがたいです。

15
dead_jake

Cでは、構造を宣言する方法が2つあります。

struct STRUCT_NAME {} ;

または

typedef struct {} STRUCT_ALIAS;

最初の方法を使用する場合(構造体に名前を付ける)-変数を明示的にa structとしてマークして変数を定義する必要があります。

struct STRUCT_NAME myStruct;

ただし、2番目の方法(構造体にエイリアスを与える)を使用する場合は、struct識別子を省略できます。コンパイラは、aliasだけを指定すると、変数のタイプを推定できます。

STRUCT_ALIAS myStruct;

ボーナスポイント:構造体は名前とエイリアスの両方で宣言できます:

typedef struct STRUCT_TAG {} STRUCT_TAG;
// here STRUCT_NAME == STRUCT_ALIAS

次に、変数の定義で、1番目または2番目の方法を使用できます。なぜ2つの世界の両方が良いのですか? Structエイリアスを使用すると、構造体変数の定義を短くすることができます。これはときどき良いことです。しかし、構造体名を使用すると、forward declarationsを作成できます。これは、いくつかの場合に不可欠なツールです-構造体の間に循環参照があることを考慮してください:

struct A {
  struct B * b;
}
struct B {
  struct A * a;
}

さらに、このアーキテクチャには欠陥がある可能性があります-この循環定義は、構造体が最初に(名前で)宣言され、構造体ポインタがstructとして明示的に参照されるとコンパイルされます。

27

新しいタイプを定義する必要がある場合は、次のように記述する必要があります。

typedef struct {

    int p;
    double h;
    double hfov;
    double vfov;
} georeg_val ;

その後、georeg_valを新しいタイプとして使用できます。

8
Gabriel

構造体タイプの定義(この例では、バイナリ検索ツリー構造体):

struct tree { 
  int info;
  struct tree *left;
  struct tree *right;
} 

typedef struct tree treeNode;

関数の宣言。例:

treeNode *insertElement(treeNode *treeA, int number);
4
Lucas Ferreira