C - Typedef とは何ですか? 使い方?便利なことは何ですか?

Typedef とは何ですか?

typedefC言語の特徴的な関数で、新しい型名を生成するために使用され、その機能は「type def(ine)」という名前からも分かります。typedefUnix のプログラムの機能と同様に、複数の名前が実際には同じプログラムに対応するように、aliasオブジェクトに別の名前を追加しますが、操作のオブジェクトはデータ型です。つまり、データ型に「ニックネーム」を付けます。ニックネーム 数字の最初の文字は通常大文字で、基本データ型ではないことを示すために使用されますtypedeftypedef

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 つの利点があります。

  1. 移植性を向上させるパラメトリック プログラム。この点は、現在では開発にはあまり役に立ちませんが、初期のコンピューター クラスのデータ型はコンピューターによって異なり、サイズやデータ型の名前も異なります。使用する場合はtypedef移植時に一部修正するだけで済みますtypedef標準ライブラリにはsize_t2ptrdiff_tつのケースがあります。
  2. 複雑なデータ型ではポインターを理解するのが難しくなり、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 *);

もっと簡単ではないでしょうか。同様の関数が同時に複数ある場合は、同じ行に記述することもでき、より簡潔になります。

困っている方のお役に立てれば幸いです~

おすすめ

転載: blog.csdn.net/qq_33919450/article/details/130391660