首页 > 其他分享 >21. C语言 `typedef`:类型重命名

21. C语言 `typedef`:类型重命名

时间:2025-01-22 11:28:04浏览次数:3  
标签:typedef 21 int 别名 C语言 book 类型 define

本章目录:


前言

在 C 语言中,typedef 是一个非常有用的关键字,它允许我们为现有的类型定义一个新的名字。这对于提高代码的可读性、简化复杂类型的声明以及减少错误非常有帮助。本文将详细探讨 typedef 的功能、使用场景以及与 #define 的区别,帮助你更好地理解和使用 typedef


1. 什么是 typedef

typedef 关键字用于为已有的类型(如基本数据类型、结构体、指针类型等)创建一个新的别名。它不会创建新的类型,只是为现有类型提供一个更具描述性的名字。typedef 主要用于提高代码的可读性和简化复杂的类型声明。

语法

typedef existing_type new_type_name;

在这个声明中,existing_type 是已存在的类型(可以是基本数据类型、结构体、指针等),而 new_type_name 是你想为这个类型定义的新名字。

示例:基本类型的别名

#include <stdio.h>

typedef unsigned char BYTE;

int main() {
    BYTE b1, b2;
    b1 = 10;
    b2 = 20;
    printf("b1: %d, b2: %d\n", b1, b2);
    return 0;
}

在上面的示例中,BYTE 成为了 unsigned char 的别名。通过 typedef,我们为 unsigned char 类型创建了一个更简洁且更具语义的名字 BYTE,使得代码更具可读性。

2. typedef 为结构体定义别名

typedef 在结构体类型中使用得非常广泛,尤其是在处理复杂的结构体时,它能显著简化变量的声明。

示例:为结构体定义别名

#include <stdio.h>
#include <string.h>

typedef struct Books {
    char title[50];
    char author[50];
    char subject[100];
    int book_id;
} Book;

int main() {
    Book book;

    strcpy(book.title, "C 教程");
    strcpy(book.author, "Runoob");
    strcpy(book.subject, "编程语言");
    book.book_id = 12345;

    printf("书标题 : %s\n", book.title);
    printf("书作者 : %s\n", book.author);
    printf("书类目 : %s\n", book.subject);
    printf("书 ID : %d\n", book.book_id);

    return 0;
}

通过使用 typedef,我们为 struct Books 类型创建了一个新的类型名 Book,从而在后续的代码中直接使用 Book 来声明变量。这比每次都写 struct Books 要方便很多。

3. typedef vs #define:两者的区别

虽然 typedef#define 都能够为类型创建别名,但它们之间有显著的差异。了解这些差异将帮助我们在不同场景中做出更合适的选择。

(1) 作用范围和处理方式

  • typedef 由编译器在编译时解析,它是类型别名的声明,并且只能用于为现有类型定义别名。
  • #define 是预处理器指令,在编译前由预处理器进行文本替换,它不仅可以为类型定义别名,还能为常量、表达式等定义别名。

(2) 类型别名的处理

typedef 的类型别名会被编译器识别并进行适当的类型检查,而 #define 只是简单的文本替换。例如:

#define INTERGE int
unsigned INTERGE n;  // 没问题

typedef int INTERGE;
unsigned INTERGE n;  // 错误,不能在 INTERGE 前添加 unsigned

#define 中,INTERGE 被简单地替换为 int,因此在 unsigned INTERGE n 中,INTERGE 会被替换为 int,这会导致变量 n 被定义为 unsigned int 类型。而 typedef 在定义时是严格的,不能在类型别名前再添加修饰符。

(3) 多个变量的声明

当你使用 typedef 时,所有声明的变量都会是同一类型,而 #define 无法保证这一点。例如:

#define PTR_INT int *
PTR_INT p1, p2;  // 错误,p1 是指针,p2 不是

typedef int * PTR_INT;
PTR_INT p1, p2;  // 正确,p1 和 p2 都是指针类型

#define PTR_INT int * 会把 PTR_INT 替换为 int *,因此 p1 成为指向 int 的指针,但 p2 则不是指针类型。而使用 typedef 时,PTR_INT 会同时作用于 p1p2,使它们都成为指针类型。

(4) 宏展开与编译器处理

#define 是由预处理器进行宏展开处理,而 typedef 由编译器解析。预处理器在处理 #define 时不会进行类型检查,而 typedef 会。

#define BYTE unsigned char
BYTE b1, b2;  // 无法保证类型的正确性

typedef unsigned char BYTE;
BYTE b1, b2;  // 类型检查会进行,确保一致性

4. typedef 的其他应用

(1) 为数组类型创建别名

你还可以使用 typedef 为数组类型创建别名,从而简化数组的声明和使用。

typedef int A[6];  // 定义一个新类型 A,它表示一个长度为 6 的整型数组
A a, b;  // a 和 b 都是 int[6] 类型的数组

(2) 为复杂声明简化类型

在处理复杂的声明时,typedef 可以帮助我们简化类型声明,尤其是在函数指针的使用中。

示例:为函数指针类型创建别名
typedef int *(*pFun)(int, char*);  // 定义一个函数指针类型

pFun a[5];  // a 是一个包含 5 个函数指针的数组

在这个例子中,pFun 是一个指向函数的指针类型,它接受一个 int 和一个 char* 类型的参数,返回 int* 类型的指针。通过 typedef,我们将复杂的声明变得更容易理解和使用。


5. 总结

typedef 是 C 语言中一个非常强大的工具,它可以让我们为类型创建别名,从而使代码更加简洁、可读性更强,并且有助于减少错误。相比于 #definetypedef 提供了更多的类型安全性和灵活性。在处理复杂类型、结构体、数组以及函数指针等时,typedef 是一个非常有用的工具。

#define 的对比总结:

  • 作用范围typedef 仅用于类型别名,#define 可用于类型、常量等的替换。
  • 类型检查typedef 由编译器处理,具备类型检查;#define 仅为文本替换,不做类型检查。
  • 代码简化typedef 在多变量声明中确保一致性,#define 则无法做到这一点。

掌握 typedef 的用法,将使你的 C 语言编程更为高效、简洁,并且能够在团队协作中提升代码的可读性和可维护性。


标签:typedef,21,int,别名,C语言,book,类型,define
From: https://blog.csdn.net/wzt001005/article/details/144891412

相关文章

  • 20. C语言 位域(Bit-field)
    本章目录:前言什么是位域?如何定义位域?示例位域的内存分配位域的使用场景节省内存网络协议文件解析位域的限制位域的常见错误进阶示例:位域与指针总结前言在C语言中,位域(Bit-field)是一种特殊的结构体成员,它允许我们按位定义成员的大小。这对于存储具有明确大小限制......
  • 2025.1.21——1300
    2025.1.21——1300A1300Qingshanhasastring\(s\)whichonlycontains\(\texttt{0}\)and\(\texttt{1}\).Astring\(a\)oflength\(k\)isgoodifandonlyif\(a_i\nea_{k-i+1}\)forall\(i=1,2,\ldots,k\).ForDiv.2contestants,......
  • 25/1/21 模拟赛做题记录
    最不会的一集。B题意Alice喜欢旅游,在这个假期里他将沿着公路骑行。可供Alice选择的道路构成了一张连通无向图,Alice的起点位于\(1\)号点,终点位于\(n\)号点,每条道路有一个困难度\(v_i\)。定义一条路径的疲劳度为他路上经过的所有道路的困难度的最大值。一开始Alice......
  • C语言的循环结构
    循环结构是编程语言中的一种重要结构,用于重复执行一段代码。主要有三种循环结构:for循环,while循环和do-while循环。循环结构(1)当型循环结构:当条件P成立(为真)时,反复执行循环语句,直到条件P不成立(为假)时结束循环。(条件成立,才执行循环语句,for、while)(2)直到型循环结构:先......
  • 2025/1/21学习
    #include<bits/stdc++.h>usingnamespacestd;#defineintlonglongconstintN=1e5+10;intMax,Min,n,t;inta[N],b[N];boolcheck(intx){intlim=Max-x;intL=-1,R;for(inti=1;i<=n;++i){b[i]=a[i];if(a[i]<li......
  • C语言/C++——递归、递推、动态规划
    什么是动态规划:给定一个问题,我们把他拆成一个个子问题,直到子问题可以直接解决。然后把子问题的答案保存起来,以减少重复计算。再根据子问题的答案反推,得出原问题解的一种方法递归的过程:"递"的过程是分解子问题的过程;(dfs是第归的一种)            “归......
  • 日常训练2025-1-21
    日常训练2025-1-21E双生双宿之错rating:1300https://ac.nowcoder.com/acm/contest/95323/E思路(数论)本题考查中位数定理,中位数有这样的性质:所有数与中位数的绝对差之和最小。中位数是数列中间的那个数,或者是中间的那两个数之一。所以最后得到的双生数组中的两种数即为数列......
  • 数据结构之链表(linked list)代码实现(小白轻松懂,C语言版)
    一、前言:链表的简单介绍链表(LinkedList)是一种重要的线性数据结构,它以节点(Node)的形式存储数据,每个节点通过指针(或引用)指向下一个节点,从而形成一个动态的数据链条。与数组不同,链表的内存分配并不连续,因此具有更灵活的插入和删除操作,但在随机访问元素时效率相对较低。链表通......
  • C语言的那点事第五篇:编程界的“外卖小哥”函数
    函数就像是编程界的“外卖小哥”,帮你把任务分解成小块,然后把结果送回来。别担心,我会用幽默的方式带你飞驰在这个奇妙的世界里。咱们开始吧!1.函数定义与调用外卖小哥的职责:想象一下,你每天都要做饭,但每次都从头开始,那得多累啊!函数就像是你的“外卖小哥”,帮你把任务分解成小......
  • 2025 年 IPTV/APTV 直播源m3u(1月21日更新)
    前言注意:仅供学术学习研究使用。⚠️长期更新,建议收藏!更新日志源不在多,而在于精。0930将直播源做了较大更新,删除了大量不可用源地址。1月21日新增IPTV源:https://iptv.hacks.tools/1月21日新增直播源网站1月1日更新确认源可用性。1016新......