您的当前位置:首页正文

【C语言】深度解析typedef

2024-11-29 来源:个人技术集锦

typedef是C语言的关键字,它允许我们为各种数据类型定义新名字,下面是typedef的几种常用情况:

typedef int a;

typedef char *ptr;

typedef int buffer[10];

typedef struct
{
    int value;
    int name;
}student;

typedef int (*function)(int a, int b);

在讲它的用法之前,我们先来捋一下它的概念,《C Primer Plus》中是这样介绍的:“typedef创建的符号名只受限于类型,不能用于值。”结合我昨天的文章写的声明和定义的区别,意思就是说:typedef创建的符号名是一种声明,而非定义,即typedef创建的符号名并不会分配内存。
所以再来看刚才说得几种typedef创建的符号名,如果将typedef拿掉:

int a;

char *ptr;

int buffer[10];

struct
{
    int value;
    int name;
}student;

int (*function)(int a, int b);

那么它们就是各种类型的定义。

我们将每一行分开来讲他们的区别:
变量:
定义了一个叫a的变量。

int a;

给int类型声明了一个符号名:a。

typedef int a;
a b;//等同于 int b;

指针:
定义了一个字符型的指针。

char *ptr;

给字符型指针声明了一个符号名:ptr。

typedef char *ptr;
ptr pointer;//等同于 char * pointer

数组:
声明一个结构体类型,并使用该结构体类型定义一个名字为student的结构体。

struct
{
    int value;
    int name;
}student;
声明一个结构体类型,并给该结构体类型声明一个符号名:student
typedef struct
{
    int value;
    int name;
}student;

student s_sturct;
/*
等同于以下定义
struct
{
    int value;
    int name;
}s_sturct;;
*/

在这几种示例中,typedef的用法相对简单明了,如果透过这两个示例将typedef的用法理解为像#define一样的展开替换,那么接下来的用法就会让人难以理解。

如果按照上述的说法,那么以下的声明就应该解释为给int取了一个别名叫做buffer[10],如果真的用buffer[10]去定义变量,编译器就会报错,所以显然不能简单理解为展开替换。

typedef int buffer[10];

正确的理解是:typedef是用于为数据类型声明一个新的符号名。有了这个认知,再来看刚才的代码,如果是定义该数组,那么写法如下:

int buffer[10];

定义了一个整型数组,它的名字是buffer,拿掉名字就是它的类型:一个包含十个元素的int型数组。
所以typedef int buffer[10]的正确理解是,为一个包含十个元素的int型数组创建一个符号名。我们可以用这个新的符号名来定义数组,所定义的数组类型都是:一个包含十个元素的int型数组。

int buffer[10];

buffer text;//text是一个int型数组,内含是个元素。

接下来理解函数指针也是同义,定义了一个名字叫function的函数指针,,把该函数指针的名字拿掉,就是它声明的类型:声明了一个函数指针,它可以指向有两个int型参数,且返回值也为int型数据的函数。

int (*function)(int a, int b);

所以,加上typedef后的理解为,为该类型的函数指针创建一个符号名:function。

Typedef int (*function)(int a, int b);
function f_ptr;//f_ptr是一个int (*)(int a, int b)型的函数指针

总的来说,typedef本身并不复杂,简单的理解就是,它可以为各种不同的数据类型创建一个符号名,但是当它为一些复杂的变量类型创建符号名的时候,看起来就会令很多不熟悉的小伙伴比较困扰。

显示全文