web-dev-qa-db-ja.com

typedefと#defineはcで同じですか?

typedef#definec ?で同じです

111
user188276

番号。

#defineはプリプロセッサトークンです。コンパイラ自体はそれを認識しません。
typedefはコンパイラトークンです。プリプロセッサはそれを気にしません。

どちらか一方を使用して同じ効果を達成できますが、ニーズに合った適切なものを使用することをお勧めします

#define MY_TYPE int
typedef int My_Type;

物事が「毛むくじゃら」になったら、適切なツールを使用することで適切になります

#define FX_TYPE void (*)(int)
typedef void (*stdfx)(int);

void fx_typ(stdfx fx); /* ok */
void fx_def(FX_TYPE fx); /* error */
110
pmg

typedefは変数のようにスコープ規則に従いますが、defineはコンパイル単位の終わりまで(または一致するundefまで)有効です。

また、typedefではできないこともありますが、defineではできません。
例えば:

typedef int* int_p1;
int_p1 a, b, c;  // a, b, c are all int pointers

#define int_p2 int*
int_p2 a, b, c;  // only the first is a pointer, because int_p2
                 // is replaced with int*, producing: int* a, b, c
                 // which should be read as: int *a, b, c
typedef int a10[10];
a10 a, b, c;  // create three 10-int arrays
typedef int (*func_p) (int);
func_p fp;  // func_p is a pointer to a function that
            // takes an int and returns an int
212
Andreas Grech

いいえ、それらは同じではありません。例えば:

#define INTPTR int*
...
INTPTR a, b;

前処理の後、その行は

int* a, b;

うまくいけば、問題が表示されます。タイプはaのみになりますint *; bは、プレーンintとして宣言されます(*は、型指定子ではなく、宣言子に関連付けられています)。

対照的に

typedef int *INTPTR;
...
INTPTR a, b;

この場合、abの両方のタイプはint *

関数や配列へのポインタなど、プリプロセッサマクロではエミュレートできないtypedefのクラス全体があります。

typedef int (*CALLBACK)(void);
typedef int *(*(*OBNOXIOUSFUNC)(void))[20]; 
...
CALLBACK aCallbackFunc;        // aCallbackFunc is a pointer to a function 
                               // returning int
OBNOXIOUSFUNC anObnoxiousFunc; // anObnoxiousFunc is a pointer to a function
                               // returning a pointer to a 20-element array
                               // of pointers to int

プリプロセッサマクロでそれを試してください。

21
John Bode

#define はマクロを定義します。
typedefはタイプを定義します。

さて、ここにいくつかの違いがあります:

#defineを使用すると、コンパイル時に使用できる定数を定義できます。定数を#ifdefと共に使用して、コードのコンパイル方法を確認し、コンパイルパラメーターに従って特定のコードを特殊化できます。
#defineを使用して、ミニチュアの検索と置換を宣言することもできますマクロ関数

typedefを使用して型にエイリアスを与えることができます(おそらく#defineでも可能です)が、 #define定数の検索と置換の性質。
それ以外に、前方宣言typedefを使用して、使用するタイプを宣言しますが、書き込み中のファイルにはまだリンクされていません。

12
Yochai Timmer

プリプロセッサマクロ( "#define 's ")は、「検索と置換」に似た字句解析ツールです。これらはプログラミング言語に完全にとらわれておらず、何をしようとしているのか理解できません。 -時折それは便利ですが、注意して使用する必要があります。

Typedefは、型のエイリアスを作成できるC言語の機能です。これは、複雑な複合型(構造体や関数ポインタなど)を読み取り可能および処理可能にするのに非常に便利です(C++では、must typedef a type)の状況もあります。

(3)の場合:可能な場合は、プリプロセッサマクロよりも言語機能を常に優先する必要があります。したがって、型には常にtypedefを使用し、定数には定数値を使用します。そうすれば、コンパイラは実際にあなたと有意義に対話できます。コンパイラはあなたの友人であることに注意してください。可能な限り伝えてください。プリプロセッサマクロは、コンパイラからのセマンティクス非表示によって正反対を行います。

6
Kerrek SB

これらは非常に異なっていますが、カスタムデータ型を実装するためによく使用されます(この質問がすべてだと思います)。

言及したように、#defineは、コンパイラーがコードを見る前に(カットアンドペースト操作のように)プリプロセッサーによって処理され、typedefはコンパイラーによって解釈されます。

(少なくともデータ型の定義に関して)主な違いの1つは、typedefがより具体的な型チェックを許可することです。例えば、

#define defType int
typedef int tdType

defType x;
tdType y;

ここで、コンパイラは変数xをintとして認識しますが、変数yは、たまたまintと同じサイズである 'tdType'と呼ばれるデータ型として認識します。 defType型のパラメーターを取る関数を作成した場合、呼び出し元は通常のintを渡すことができ、コンパイラーはその違いを知りません。関数が代わりにtdType型のパラメーターを取る場合、コンパイラーは、関数呼び出し中に適切な型の変数が使用されたことを確認します。

また、一部のデバッガーはtypedefsを処理する機能を備えています。これは、すべてのカスタム型を基本プリミティブ型としてリストするよりもはるかに便利です(#defineが代わりに使用されました)。

3
bta

番号。
typedef は、タイプのエイリアスを作成するCキーワードです。
#defineはプリプロセッサ命令で、コンパイル前にテキスト置換イベントを作成します。コンパイラがコードに到達すると、元の「#defined」Wordはもう存在しません。 #defineは、主にマクロとグローバル定数に使用されます。

2

私の知る限り.

'typedef'は、既存のデータ型に「エイリアス」を設定するのに役立ちます。例えばtypedef char chr;

#defineは、マクロまたは一般的なパターン置換を定義するために使用されるプリプロセッサディレクティブです。例えば#define MAX 100、MAXのすべての出現を100で置換

1
user59634

誰もが上で言ったように、彼らは同じではありません。答えのほとんどは、typedef#defineよりも有利であることを示しています。しかし、#defineのプラスポイントを付けさせてください:
コードが非常に大きく、多くのファイルに散らばっている場合は、#defineを使用することをお勧めします。読みやすさに役立ちます。すべてのコードを前処理して、変数の実際の型定義を宣言自体の場所で確認できます。

0
abcoep