Typedef とは何ですか?
typedef
C言語の特徴的な関数で、新しい型名を生成するために使用され、その機能は「type def(ine)」という名前からも分かります。typedef
Unix のプログラムの機能と同様に、複数の名前が実際には同じプログラムに対応するように、alias
オブジェクトに別の名前を追加しますが、操作のオブジェクトはデータ型です。つまり、データ型に「ニックネーム」を付けます。ニックネーム 数字の最初の文字は通常大文字で、基本データ型ではないことを示すために使用されます。typedef
typedef
C言語ではtypedef
マクロとよく似ており、マクロとの違いを理解する前に理解する必要があるため、両者の違いを#define
最後に記載しています。typedef
Typedef はどのように使用されますか?
たとえば、C 言語には、char
型の配列である文字列の概念があり、最後の要素は\0
文字列の終わりです。そして、要素型の配列は実際にはポインターからポインターchar
と同等です。char
しかし、C 言語にはそのようなデータ型はありませんString
。次に、次のステートメントを使用して同等の機能を実現できます。
//String是一个指针,*String(就是该指针的内容)等于char。换句话说,String 等于 char *
typedef char *String
typedef
ここから、ニックネームが後ろではなく、データ型の後ろの変数の位置にあることもわかります。(C言語で変数を宣言・定義する場合、変数は型の後にありますか?)
このとき、以下のステートメントを使用して「文字列」型のデータを宣言、代入、出力することができます。次のように:
#include <stdio.h>
int main()
{
typedef char *String;
String p = "abc";
printf("%s\n", p);
return 0;
}
出力は次のとおりです。
abc
繰り返しになりますが、typedef
新しいデータ型は作成されず、単に「ニックネーム」が作成されるだけであり、ここでの文字列も C 言語自体の仕組みによって実現されます。
もちろん、この方法はあまり一般的ではありません。ほとんどの場合、基本データ型には「ニックネーム」が付けられません。結局のところ、ほとんどの基本データ型の名前はすでに非常に簡潔で理解しやすいものになっており、文字列は例外です。最も一般的なのは、構造体のカスタム データ型を使用するときに、typedef
より単純または理解しやすい同義語を見つけることです。これにより、コードがより簡潔で効率的になることもあります。
たとえば、次のコードは古典的なバイナリ ツリー ノード構造です。
struct tnode {
char *word;
int count;
struct tnode *left;
struct tnode *right;
};
新しいノードを作成し、次のようにスペースを割り当てます。
struct tnode *talloc(void)
{
return (struct tnode *) malloc(sizeof(struct tnode));
}
このメソッドを使用する場合typedef
、つまり構造体を宣言する場合はtnode
、次のようにtypedef
「ニックネーム」を付けます。Treenode
typedef struct tnode {
char *word;
int count;
Treeptr left;
Treeptr right;
} Treenode;
次に、 を使用してtypedef
「ニックネーム」を定義します*Treeptr
。
typedef struct tnode *Treeptr;
*
この場合、メモリの作成と割り当ての方法は簡潔であるだけでなく、次のようにポインタ記号を使用しないスタイルで記述することもできます。
Treenode talloc(void)
{
return (Treeptr) malloc(sizeof(struct Treenode));
}
以前のバージョンと比べて、かなり分かりやすくなったでしょうか?
Typedef はどのくらい便利ですか?
typedef
と の主な目的#define
は、コードをより簡潔にすること、つまりコードをより美しくすることです。
さらに、typedef
次の 2 つの利点があります。
- 移植性を向上させるパラメトリック プログラム。この点は、現在では開発にはあまり役に立ちませんが、初期のコンピューター クラスのデータ型はコンピューターによって異なり、サイズやデータ型の名前も異なります。使用する場合は
typedef
移植時に一部修正するだけで済みますtypedef
。標準ライブラリにはsize_t
2ptrdiff_t
つのケースがあります。 - 複雑なデータ型ではポインターを理解するのが難しくなり、
typedef
ポインターを使用する方がはるかに簡単になるため、コードを理解しやすくします。前のセクションのものは一talloc
例です。
Typedef と #define の違い
次に、との違いを説明しますtypedef
。#define
typedef
との主な目的#define
はコードをより簡潔にすることなので、どちらもテキストを置換する機能があります。2 つの違いは、typedef
テキスト置換はコンパイラが理解できるため、マクロよりもはるかに強力であることです。
マクロは、テキストの直接置換、単純な計算や演算など、単純なテキスト置換のみを行うことができます。テキスト置換の簡単な例を次に示します。
#define MAXWORD 100
int a[MAXWORD];
コンパイル時は直接 にint a[MAXWORD];
置換int a[100];
、つまりテキスト置換してからコンパイルし、MAXWORD
変数や定数としてコンパイルすることはありません。したがって、マクロが属するスコープはプリプロセッサ (Preprocessor) とも呼ばれます。
これを使用するとtypedef
、いくつかの複雑な機能を実現できます。たとえば、次のコード行は新しい type を作成するものですPFI
。これは 2 つのパラメータを持つ関数へのポインタであり、パラメータの型は でchar *
、戻り値は次int
のとおりです。
typedef int (*PFI)(char *, char *);
これは、次の関数などの一部の関数を宣言するときに非常に便利です。
int strcmp(char *s, char *t)
{
for ( ; *s == *t; s++, t++) {
if (*s == '\0') {
return 0;
}
}
return *s - *t;
}
宣言するときは次のように記述できます。
PFI strcmp;
オリジナルと比較して
int strcmp(char *, char *);
もっと簡単ではないでしょうか。同様の関数が同時に複数ある場合は、同じ行に記述することもでき、より簡潔になります。
困っている方のお役に立てれば幸いです~