ホームページ >バックエンド開発 >C#.Net チュートリアル >C言語でのtypedefの用途は何ですか?

C言語でのtypedefの用途は何ですか?

青灯夜游
青灯夜游オリジナル
2020-07-18 14:23:2934648ブラウズ

typedef の使用法は次のとおりです: 1. 基本データ型の新しい型名を定義します。 2. カスタム データ型 (構造体、共用体、列挙型) の簡潔な型名を定義します。 3. 配列の簡潔な型名を定義します。 ; 4. ポインタの簡潔な名前を定義します。

C言語でのtypedefの用途は何ですか?

C 言語では、ユーザーが typedef キーワードを使用して独自のカスタム データ型名を定義し、システムのデフォルトの基本型名、配列型名、およびポインターを置き換えることができます。名前とユーザー定義の構造名、共有名、列挙名など。

ユーザーがプログラム内で独自のデータ型名を定義すると、プログラム内で独自のデータ型名を使用して、変数の型、配列の型、ポインタ変数の型、および型を定義できます。機能の説明など。

たとえば、C 言語は C99 より前にはブール型を提供していませんでしたが、次のコードに示すように、typedef キーワードを使用して単純なブール型を定義できます。その後は、次のコードに示すように、基本的な型データと同じように使用できます。

typedef int BOOL;
#define TRUE 1
#define FALSE 0

typedef を使用する 4 つの方法 #実際に使用する場合、typedef の用途は主に 4 種類あります。

1. 基本データ型の新しい型名を定義する

言い換えると、システム内のすべての基本型は、デフォルトで typedef キーワードを使用して型名を再定義できます。 . サンプル コードは次のとおりです:

BOOL bflag=TRUE;

さらに、このメソッドを使用してプラットフォームに依存しない型を定義することもできます。たとえば、ターゲット プラットフォーム 1 で REAL という浮動小数点型を定義するには、これを最高精度の型、つまり次のように表します。

typedef unsigned int COUNT;

Long double をサポートしないプラットフォーム 2 では、これを次のように変更します。 # #
typedef long double REAL;

次のように変更することもできます:

typedef double REAL;

double さえサポートしていないプラットフォームでは、次のように変更します:

typedef float REAL;

このようにして、プログラムを移植するときは、プラットフォームの場合、typedef の定義を変更するだけでよく、他のソース コードを変更する必要はありません。実際、この手法は標準ライブラリで広く使用されており、たとえば、VC 2010 の crtdefs.h ファイルの size_t の定義は次のようになります:

#ifndef _SIZE_T_DEFINED
#ifdef  _WIN64
typedef unsigned __int64    size_t;
#else
typedef _W64 unsigned int   size_t;
#endif
#define _SIZE_T_DEFINED
#endif

2. これはカスタム データです。 type (構造体、共用体、列挙型) は簡潔な型名を定義します

構造体を例として、以下に Point:

struct Point
{
    double x;
    double y;
    double z;
};

という名前の構造体を定義します。この構造体を呼び出すとき、この構造体を次のコードのように呼び出す必要があります:

struct Point oPoint1={100,100,0};
struct Point oPoint2;

ここで、構造体 struct Point は新しいデータ型です。変数を定義するときは、上記の呼び出しメソッドと同じ予約が必要です。Word struct、ではなくPoint を直接使用して int や double などの変数を定義します。ここで、次のコードに示すように、typedef を使用してこの構造体を定義します。

typedef struct tagPoint
{
    double x;
    double y;
    double z;
} Point;

上記のコードでは、実際には 2 つの操作が完了します:

1)、新しい構造体の型を定義します。

struct tagPoint
{
    double x;
    double y;
    double z;
} ;

このうち、struct キーワードと tagPoint がこの構造体型を構成し、typedef キーワードの有無に関係なく存在します。

2) typedef を使用して、この新しい構造体に Point というエイリアスを付けます。つまり、

typedef struct tagPoint Point

したがって、次のように、Point を直接使用して int や double などの変数を定義できるようになります。次のコード:

Point oPoint1={100,100,0};
Point oPoint2;

typedef についての理解を深めるために、次のコードに示す構造の例を見てみましょう:

typedef struct tagNode
{
    char *pItem;
    pNode pNext;
} *pNode;

表面的には、上記のサンプル コードは次のとおりです。先ほどと同じように定義されているので問題ありません。しかし、コンパイラがエラーを報告しました。なぜでしょうか? C言語では構造体にそれ自体へのポインタを含めることができないのでしょうか?

実際、問題は構造体の定義自体ではありません。C 言語では構造体にそれ自体へのポインタを含めることができることは誰もが知っているはずです。これらの多くは、リンク リストなどのデータ構造の実装で見られます。 .クラスの例。だから問題は何ですか?実際、根本的な問題は依然として typedef の適用にあります。

上記のコードでは、新しい構造の確立中に pNext 宣言が出現し、そのタイプは pNode です。ここで、pNode が構造の新しいエイリアスを表すことに注意することが重要です。構造型自体が作成されていない場合、この構造型の新しいエイリアスがまだ存在しないため、コンパイラは pNode をまったく認識せず、当然エラーが報告されます。したがって、構造体の pNext 宣言を

typedef struct tagNode
{
    char *pItem;
    struct tagNode *pNext;
} *pNode;

のように変更するか、次のコードに示すように struct と typedef を個別に定義するなど、いくつかの適切な調整を行う必要があります。

typedef struct tagNode *pNode;
struct tagNode
{
    char *pItem;
    pNode pNext;
};

上記のコードでは、typedef を使用して、完全に宣言されていない型 tagNode に新しいエイリアスを与えます。ただし、この方法は C コンパイラで完全にサポートされていますが、お勧めできません。次の標準定義方法を使用することをお勧めします:

struct tagNode
{
    char *pItem;
    struct tagNode *pNext;
};
typedef struct tagNode *pNode;

3、为数组定义简洁的类型名称

它的定义方法很简单,与为基本数据类型定义新的别名方法一样,示例代码如下所示:

typedef int INT_ARRAY_100[100];
INT_ARRAY_100 arr;

4、为指针定义简洁的名称

对于指针,我们同样可以使用下面的方式来定义一个新的别名:

typedef char* PCHAR;
PCHAR pa;

对于上面这种简单的变量声明,使用 typedef 来定义一个新的别名或许会感觉意义不大,但在比较复杂的变量声明中,typedef 的优势马上就体现出来了,如下面的示例代码所示:

int *(*a[5])(int,char*);

对于上面变量的声明,如果我们使用 typdef 来给它定义一个别名,这会非常有意义,如下面的代码所示:

// PFun是我们创建的一个类型别名
typedef int *(*PFun)(int,char*);
// 使用定义的新类型来声明对象,等价于int*(*a[5])(int,char*);
PFun a[5];

小心使用 typedef 带来的陷阱

接下来看一个简单的 typedef 使用示例,如下面的代码所示:

typedef char* PCHAR;
int strcmp(const PCHAR,const PCHAR);

在上面的代码中,“const PCHAR” 是否相当于 “const char*” 呢?

答案是否定的,原因很简单,typedef 是用来定义一种类型的新别名的,它不同于宏,不是简单的字符串替换。因此,“const PCHAR”中的 const 给予了整个指针本身常量性,也就是形成了常量指针“char*const(一个指向char的常量指针)”。即它实际上相当于“char*const”,而不是“const char*(指向常量 char 的指针)”。当然,要想让 const PCHAR 相当于 const char* 也很容易,如下面的代码所示:

typedef const char* PCHAR;
int strcmp(PCHAR, PCHAR);

其实,无论什么时候,只要为指针声明 typedef,那么就应该在最终的 typedef 名称中加一个 const,以使得该指针本身是常量。

还需要特别注意的是,虽然 typedef 并不真正影响对象的存储特性,但在语法上它还是一个存储类的关键字,就像 auto、extern、static 和 register 等关键字一样。因此,像下面这种声明方式是不可行的:

typedef static int INT_STATIC;

不可行的原因是不能声明多个存储类关键字,由于 typedef 已经占据了存储类关键字的位置,因此,在 typedef 声明中就不能够再使用 static 或任何其他存储类关键字了。当然,编译器也会报错,如在 VC++2010 中的报错信息为“无法指定多个存储类”。

相关推荐:《c语言教程

以上がC言語でのtypedefの用途は何ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。