2016-11-21 3 views
1

今週のC ANSI言語の特徴と大きな課題を学びます。ポインタ付きのtypedefの宣言

練習では、関数のシグネチャの宣言がいくつかあるヘッダーファイルがあります。

この1つは私の注意を引いた:

typedef struct image * Image; 

私は私の.cファイルでこれを試してみました:だから

imagePGM.c:22:3: erreur: conflicting types for ‘Image’ 
} Image; 

typedef struct { 
    char nbrMagique[10]; 
    unsigned long imgLarg; 
    unsigned long imgHaut; 
    unsigned long imgSeuilMax; 
    unsigned long **imageMatrice; 
} Image; 

しかし、コンパイル時に常にエラーを持つ続けます私は.cファイルの構造体を再定義することはできないので、ヘッダーのいずれかに触れることはできないと思います。

"typedef struct image * Image;を尊重すること。 .hヘッダーファイルで、私は動的な2次元テーブルを作成し、それにポインタ*画像を向けなければなりませんか?

私の見解には何かが欠けていますか?

しかし、typdefのシグネチャ内のポインタ*は、.hファイルの中で何を意味していますか? typedefのセマンティクスから

+2

'Image'の二つの異なる定義をしました。一つは' struct image * 'のtypedefで、もう一つは無名structのtypedefです。一度名前をtypedefすることができます。たぶんあなたはあなたのcファイルに 'struct image {......};'を意味していたでしょう –

+0

私はstruct image * Imageを使用しなければなりません。それは確かに 私は2番目を使用することはできません。 しかし、typderの署名にあるポインタ*はどういう意味ですか? – Cyberflow

+0

これに関する情報を追加します。コンテキストは、不完全な型へのポインタを作成しようとしている可能性があります。これは_opaque pointers_と呼ばれることもあります。これはCで真のプライベートカプセル化を実現する方法です。そうであれば、それをポインタとしてtypedefしないほうが良いでしょう。 'typedef struct image image'を行い、呼び出し元にポインタ構文を使用させる方がよいでしょう。 – Lundin

答えて

3

、章§6.7.8、C11ドキュメント、ストレージクラス指定子はtypedefある宣言で

、各宣言子は意味のtypedef名である 識別子を定義します識別子に指定されたタイプ[...]

だから、基本的に、typedefは、所与のタイプに対してエイリアスを作成するために使用されます。

また、その上で展開する、

typedef宣言は新しいタイプなので、指定されたタイプのためだけ 同義語を導入しません。すなわち、次の宣言である:

typedef T type_ident;
type_ident D;

type_identDに(Tとして知られている)Tで宣言 指定子によって指定されたタイプとtypedef名前、識別子として定義されていますタイプ'' derived-declaratype- list T 'です。あなたのコードで

、あなたが問題の原因である同じエイリアス名にtypedef二つの異なるタイプ(すなわち、struct image *と無名のstruct)しようとしています。

ソリューション:あなたは言っ

struct image { 
    char nbrMagique[10]; 
    unsigned long imgLarg; 
    unsigned long imgHaut; 
    unsigned long imgSeuilMax; 
    unsigned long **imageMatrice; 
} ; 

のように、簡単な宣言を使用し、あなたの.cファイルにtypedef構造体宣言する必要はありません、一般的には、typedef -ingポインタが混乱コーディングスタイルと考えられていますこれは可読性を低下させ、IMHOはポインタの型定義を避けます。


一部

しかしtypedefの署名内のポインタ*はどういう意味については?

つまり、新しいエイリアスはポインタ型です。場合について、

typedef struct image * Image; 

両方

Image iPointer = NULL; 

struct image * againIPointer = NULL; 

は同じです。

+0

あなたのソリューションを適用しようとします。しかし、typderの署名のポインタ*はどういう意味ですか? – Cyberflow

+0

@Cyber​​flowつまり、エイリアスはポインタ型であることを意味し、私の答えはそれをカバーするために少し説明します。 –

+0

「[typedef'ポインタを使うのは良い考えですか?](http://stackoverflow.com/questions/750178/is-it-a-good-ide-to-typedef-pointers) "いいえ、彼らが関数ポインタでない限り"。 –

関連する問題