2. typedef 类型别名

typedef 关键字用于为已有的数据类型取一个别名。

typedef 的主要作用是用简单的标识符来表示复杂的数据类型,方便程序编写和阅读。

使用 typedef 只是用原有类型映射出一个新的类型别名,但并不是创建一个新的类型。也就是说使用 typedef 声明的类型别名和原类型相同,没有区别,可以替换使用。

语法:

// 为基本数据取别名
typedef 旧类型 新类型别名;

// 在定义结构体、联合体、枚举时为结构体、联合体、枚举取别名
typedef [struct|union|enum] {
    // ... 成员变量列表
} 新类型别名;

// 在定义结构体、联合体、枚举后再取别名
typedef struct|union|enum 结构体|联合体名|枚举名 新类型别名;

// 定义一维数组类型别名
typedef 数组类型 新类型别名[整数表达式];

// 定义一维数组指针类型别名
typedef 数据类型(*新类型别名)[整数表达式];

// 定义二维数组指针类型别名
typedef 数据类型(*新类型别名)[整数表达式][整数表达式];

// 定义函数指针类型别名
typedef 返回值数据类型 (*新类型别名)(形参1类型, 形参1类型,...);

说明

示例

// filename: typedef_demo.c
#include <stdio.h>

// 声明各种类型的别名, 标识符后加 _t 表示这个标识符是类型。
typedef unsigned char uint8_t;
typedef unsigned short int uint16_t;
typedef unsigned int uint32_t;
typedef unsigned long int uint64_t;

// 声明字符串型指针类型的别名
typedef const char * cstring_t;

// 定义结构体别名
typedef struct student {
    char name[32];
    int age;
} student_t;
typedef struct student stu_t;

// 定义枚举类型别名
typedef enum weekday {
    mon,
    tue,
} weekday_t;

// 定义 含有 10 个数据元素的整型一维数组
typedef int arr10_t[4] ;

// 定义 含有 10 个数据元素的整型一维数组
typedef int (*parr10_t)[4] ;

// 定义 void(int) 类型的函数的函数指针的类型别名
typedef void (*sighandler_t)(int);

void print_x(int x) {
    printf("the number is %d\n", x);
}

int main(int argc, char * argv[]) {
    // 上述类型别名的使用方法如下
    uint32_t x = 100;
    cstring_t name = "weimingze";
    student_t stu1 = {"zhang3", 18};
    stu_t stu2 = stu1;
    weekday_t today = mon;
    arr10_t scores = {70, 80, 90};
    parr10_t pscores = &scores;
    sighandler_t pfun = &print_x;

    // 使用上述数据
    printf("x: %d\n", x);
    printf("name: %s\n", name);
    printf("stu1.name: %s\n", stu1.name);
    printf("stu2.age: %d\n", stu2.age);
    printf("today: %d\n", today);
    for (x = 0; x < sizeof(scores)/sizeof(scores[0]); x++)
        printf("scores[%d]: %d\n", x, scores[x]);
    for (x = 0; x < sizeof(scores)/sizeof(scores[0]); x++)
        printf("(*pscores)[%d]: %d\n", x, (*pscores)[x]);

    pfun(200);
    return 0;
}

编译和运行结果如下:

weimingze@mzstudio:~$ gcc -o typedef_demo typedef_demo.c
weimingze@mzstudio:~$ ./typedef_demo
x: 100
name: weimingze
stu1.name: zhang3
stu2.age: 18
today: 0
scores[0]: 70
scores[1]: 80
scores[2]: 90
scores[3]: 0
(*pscores)[0]: 70
(*pscores)[1]: 80
(*pscores)[2]: 90
(*pscores)[3]: 0
the number is 200

通过上述运行结果可以看出,使用 typedef 关键字仅使用一个标识符就可以代替复杂的类型名,使用该类型声明变量也可以写成 类型别名 变量名 的方式,用起来十分方便。

练习

函数声明如下:

typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);

请问 函数 signal 的形参参数变量和返回值的类型都是什么?如果不使用 typedef void (*sighandler_t)(int); 声明函数的类型别名,这个函数 signal 函数的声明应当如何来写?尝试写出此函数 signal 的函数声明。