Cprogramming 简明教程

Typedef in C

C typedef

C 语言提供一个名为 typedef 的关键字,用于为现有 data type 设置备用名称。C 中的 typedef 关键字非常适用于为内置数据类型以及派生数据类型(例如结构体、联合或指针)分配一个方便的别名。

有时,在每次声明变量时,使用名称较长的数据类型(例如“ struct structname ”或“ unsigned int ”)会变得很笨重。在这些情况下,我们可以分配一个便捷的快捷方式来使代码更具可读性。

typedef Syntax

一般来说, typedef 关键字按如下方式使用:

typedef existing_type new_type;

typedef Examples

在本节中,让我们了解 typedef 的一些用例。

Example 1

在 C 语言中,关键字“ unsigned ”用于声明无符号整数 variables ,该整数只能存储非负值。

C 还有一个名为“ short ”的关键字,该关键字声明占用 2 个字节内存的整数数据类型。如果你想要声明一个为 short 且只能具有非负值的变量,那么可以组合这两个关键字(unsigned 和 short):

short unsigned int x;

如果要声明许多这种类型的变量,则每次使用这三个关键字都会非常不方便。相反,可以使用 typedef 关键字定义 alias 或快捷方式,如下所示−

typedef short unsigned int USHORT;

这会通知编译器,标识符 USHORT 对应于“ short unsigned int ”类型。此后,可以在变量声明语句中使用 USHORT

USHORT x;

Example 2

C 还有一个 static 关键字,表示此类变量仅初始化一次。关键字“ long ”在 64 位系统上分配 8 个字节来存储整数。我们可以声明这种类型的变量,如下所示:

static unsigned long x;

然而,我们不能在“typedef”语句中使用关键字“static”,不过,可以使用 typedef 为这种类型的声明分配一个快捷方式别名−

typedef signed long SLONG;
static SLONG x;

Note : 根据惯例,别名名称以大写字母表示,只是为了区分内置类型和使用的别名。

Example 3

以下示例演示如何在 C 程序中使用别名名称−

#include <stdio.h>

int main() {
   typedef short unsigned int USHORT;
   typedef signed long int SLONG;

   static SLONG x = 100;
   USHORT y = 200;

   printf("Size of SLONG: %d \nSize of USHORT: %d", sizeof(SLONG), sizeof(USHORT));

   return 0;
}

Output

运行此代码时,将产生以下输出−

Size of SLONG: 8
Size of USHORT: 2

Defining a Structure using Typedef

通常,我们需要通过在声明语句中添加 struct_type 的名称前缀来声明结构体变量,如下所示−

struct struct_type var;

如果以这种方式编写类型名称会感觉很麻烦,则可以使用 typedef 来分配别名−

typedef struct struct_type ALIAS;

Example

在这个示例中,我们定义了一个 structure 类型,然后使用 typedef 关键字为它设置一个别名 −

#include <stdio.h>

int main() {

   typedef unsigned long int ULONG;
   typedef short int SHORT;

   struct mystruct {
      ULONG a;
      SHORT b;
   };

   typedef struct mystruct STR;
   STR s1 = {10, 20};
   printf("%ld %u", s1.a, s1.b);

   return 0;
}

运行代码并检查其输出:

10 20

有一个 alternate approach 使用 typedef 关键字。我们可以将其组合在结构定义中,如下所示 −

typedef struct mystruct {
   ULONG a;
   SHORT b;
} STR;

STR s1 = {10, 20};

Typedef for Struct Pointer

typedef 关键字也可用于为任意 pointer 类型分配一个新标识符。通常,我们这样声明一个指针变量 −

struct mystruct * x;

相反,我们可以这样使用 typedef 关键字 −

typedef struct mystruct {
   ULONG a;
   SHORT b;
} STR;

typedef STR * strptr;

它允许你以一个更简洁的方式来声明这个类型的指针 −

strptr ptr;

然后我们可以为对应的 struct variable to the pointer 分配地址。

Example

下面的示例展示了如何使用 typedef 来创建一个结构指针 −

#include <stdio.h>

int main() {

   typedef unsigned long int ULONG;
   typedef short int SHORT;

   typedef struct mystruct {
      ULONG a;
      SHORT b;
   } STR;

   STR s1 = {10, 20};
   typedef STR * strptr;
   strptr ptr = &s1;

   printf("%d %d \n", s1.a, s1.b);
   printf("%d %d", ptr->a, ptr->b);

   return 0;
}

当你运行这段代码时,它将产生以下输出:

10 20
10 20

Typedef for Union

我们可以使用 typedef 关键字为任意 union 类型分配一个快捷别名。

Example

下面的示例展示了如何在创建联合中使用 typedef

#include <stdio.h>

int main() {

   typedef unsigned long int ULONG;
   typedef short int SHORT;

   typedef union myunion {
      char a;
      int b;
      double c;
   } UNTYPE;

   UNTYPE u1;
   u1.c = 65.50;

   typedef UNTYPE * UNPTR;
   UNPTR ptr = &u1;

   printf("a:%c b: %d c: %lf \n", u1.a, u1.b, u1.c);
   printf("a:%c b: %d c: %lf \n", ptr->a, ptr->b, ptr->c);

   return 0;
}

运行代码并检查其输出:

a: b: 0 c: 65.500000
a: b: 0 c: 65.500000

typedef vs

typedef 关键字经常与 #define 指令混淆。在 C 语言中, #define 是一个 preprocessor directive 。它是定义常量的有效方法。

使用 #definesyntax 如下 −

#define name value

对于 example

#define PI 3.14159265359

#define 语句也可以用于定义宏 −

#define SQUARE(x) x*x

一个宏的工作方式像一个函数。但是,在其被调用的时候,该值会在预处理程序级别被替换。

printf("%d", SQUARE(5));

#define 是一个预处理程序指令,而 typedef 会在编译的时候被求值。

  1. typedef 仅限于为类型提供符号名称。 #define 可以用于定义值的别名。例如,你可以定义 “1” 为 “ONE”。

  2. typedef 的解释是由编译器执行的,而 #define 语句是由预处理程序处理的。

Example

在下面的代码中,我们使用了这两个特性 ( typedef#define ) −

#include <stdio.h>
#define MAX 10

int main() {

   typedef unsigned long int ULONG;
   typedef short int SHORT;

   typedef struct employee {
      char name[MAX];
      int age;
   } EMP;

   EMP e1 = {"Krishna", 25};
   printf("Name: %s \nAge: %d", e1.name, e1.age);

   return 0;
}

当你运行这段代码时,它将产生以下输出:

Name: Krishna
Age: 25