0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

#define和typedef的真正区别

strongerHuang 来源:strongerHuang 2023-05-31 15:41 次阅读
C语言编程中,typedef 和#define是最常用语句,可能很多工作过几年的工程师都没有去深究过它们的一些用法和区别。

typedef的用法

在C/C++语言中,typedef常用来定义一个标识符及关键字的别名,它是语言编译过程的一部分,但它并不实际分配内存空间,比如:
typedef  int    INT;
typedef(int*)pINT;
typedef unsigned int  uint32_t
typedef可以增强程序的可读性,以及标识符的灵活性,但它也有“非直观性”等缺点。

#define的用法

#define为一宏定义语句,通常用它来定义常量(包括无参量与带参量),以及用来实现那些“表面似和善、背后一长串”的宏,它本身并不在编译过程中进行,而是在这之前(预处理过程)就已经完成了,但也因此难以发现潜在的错误及其它代码维护问题,比如:
#define   INT        int
#define   TRUE       1
#define   Add(a,b)   ((a)+(b));
#define   Loop_10    for (int i=0; i<10; i++)
在Scott Meyer的Effective C++一书的条款1中有关于#define语句弊端的分析,以及好的替代方法,大家可参看。

typedef与#define的区别

从以上的概念便也能基本清楚,typedef只是为了增加可读性而为标识符另起的新名称(仅仅只是个别名),而#define原本在C中是为了定义常量。到了C++,const、enum、inline的出现使它也渐渐成为了起别名的工具。 有时很容易搞不清楚 #define 与 typedef 两者到底该用哪个好,如#define INT int这样的语句,用typedef一样可以完成,用哪个好呢? 我主张用typedef,因为在早期的许多C编译器中这条语句是非法的,只是现今的编译器又做了扩充。为了尽可能地兼容,一般都遵循#define定义“可读”的常量以及一些宏语句的任务,而typedef则常用来定义关键字、冗长的类型的别名。c5e99cb6-ff81-11ed-90ce-dac502259ad0.png c603ab6a-ff81-11ed-90ce-dac502259ad0.png  宏定义只是简单的字符串代换(原地扩展),而typedef则不是原地扩展,它的新名字具有一定的封装性,以致于新命名的标识符具有更易定义变量的功能。 比如代码:
typedef    (int*)      pINT;
以及:
#define    pINT2    int*;
效果相同?实则不同!实践中见差别:pINT a,b;的效果同int *a; int *b;表示定义了两个整型指针变量。而pINT2 a,b;的效果同int *a, b; 表示定义了一个整型指针变量a和整型变量b。

typedef几种用途

用途一:定义一种类型的别名,而不只是简单的宏替换。 可以用作同时声明指针型的多个对象。比如:
char*   pa,   pb; //这多数不符合我们的意图,它只声明了一个指向字符变量的指针,和一个字符变量;
以下则可行:
typedefchar*PCHAR;
PCHARpa,pb;//同时声明了两个指向字符变量的指针
虽然下面(代码)方式也可行,但相对来说没有用typedef的形式直观,尤其在需要大量指针的地方,typedef的方式更省事。
char   *pa,   *pb;
用途二:用在旧的C代码中(具体多旧没有查),帮助struct。 以前的代码中,声明struct新对象时,必须要带上struct,即形式为:struct 结构名 对象名,如:
struct   tagPOINT1
{
  int   x;
  int   y;
};


struct   tagPOINT1   p1;
而在C++中,则可以直接写:结构名 对象名,即:
tagPOINT1   p1;
估计某人觉得经常多写一个struct太麻烦了,于是就发明了:
typedef   struct   tagPOINT
{
  int   x;
  int   y;
}POINT;


POINT   p1;   //   这样就比原来的方式少写了一个struct,比较省事,尤其在大量使用的时候
或许,在C++中,typedef的这种用途二不是很大,但是理解了它,对掌握以前的旧代码还是有帮助的,毕竟我们在项目中有可能会遇到较早些年代遗留下来的代码。 用途三:用typedef来定义与平台无关的类型。 比如定义一个叫 REAL 的浮点类型,在目标平台一上,让它表示最高精度的类型为:
typedef   long   double   REAL;
在不支持 long double 的平台二上,改为:
typedefdoubleREAL;
在连 double 都不支持的平台三上,改为:
typedeffloatREAL;
也就是说,当跨平台时,只要改下 typedef 本身就行,不用对其他源码做任何修改。标准库就广泛使用了这个技巧,比如size_t。 另外,因为typedef是定义了一种类型的新别名,不是简单的字符串替换,所以它比宏来得稳健(虽然用宏有时也可以完成以上的用途)。 用途四:为复杂的声明定义一个新的简单的别名。 方法是:在原来的声明里逐步用别名替换一部分复杂声明,如此循环,把带变量名的部分留到最后替换,得到的就是原声明的最简化版。举例如下一些情况。 1.原声明:
int   *(*a[5])(int,   char*);
变量名为a,直接用一个新别名pFun替换a就可以了:
typedef   int   *(*pFun)(int,   char*);
原声明的最简化版:
pFun   a[5];
2.原声明:
void   (*b[10])   (void   (*)());
变量名为b,先替换右边部分括号里的,pFunParam为别名一:
typedef   void   (*pFunParam)();
再替换左边的变量b,pFunx为别名二:
typedef   void   (*pFunx)(pFunParam);
原声明的最简化版:
pFunx   b[10];
3.原声明:
doube(*)()   (*e)[9];
变量名为e,先替换左边部分,pFuny为别名一:
typedef   double(*pFuny)();
再替换右边的变量e,pFunParamy为别名二
typedef   pFuny   (*pFunParamy)[9];
原声明的最简化版:
pFunParamy   e;
理解复杂声明可用的“右左法则”:从变量名看起,先往右,再往左,碰到一个圆括号就调转阅读的方向;括号内分析完就跳出括号,还是按先右后左的顺序,如此循环,直到整个声明分析完。举例:
int   (*func)(int   *p);
首先找到变量名func,外面有一对圆括号,而且左边是一个*号,这说明func是一个指针;然后跳出这个圆括号,先看右边,又遇到圆括号,这说明(*func)是一个函数,所以func是一个指向这类函数的指针,即函数指针,这类函数具有int*类型的形参,返回值类型是int。
int   (*func[5])(int   *);
func右边是一个[]运算符,说明func是具有5个元素的数组;func的左边有一个*,说明func的元素是指针(注意这里的*不是修饰func,而是修饰func[5]的,原因是[]运算符优先级比*高,func先跟[]结合)。跳出这个括号,看右边,又遇到圆括号,说明func数组的元素是函数类型的指针,它指向的函数具有int*类型的形参,返回值类型为int。 也可以记住2个模式:type (*)(....)函数指针type (*)[]数组指针

typedef的陷阱

陷阱一:记住,typedef是定义了一种类型的新别名,不同于宏,它不是简单的字符串替换。比如先定义:
typedef   char*   PSTR;
然后:
int   mystrcmp(const   PSTR,   const   PSTR);
const PSTR实际上相当于const char*吗? 不是的,它实际上相当于char* const。 原因在于const给予了整个指针本身以常量性,也就是形成了常量指针char* const。 简单来说,记住当const和typedef一起出现时,typedef不会是简单的字符串替换就行。 陷阱二:
typedef在语法上是一个存储类的关键字(如auto、extern、static、register等一样),虽然它并不真正影响对象的存储特性,如:
typedef   static   int   INT2;   //不可行
编译将失败,会提示“指定了一个以上的存储类”。 审核编辑 :李倩



声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • C++
    C++
    +关注

    关注

    22

    文章

    2108

    浏览量

    73644
  • 编译器
    +关注

    关注

    1

    文章

    1634

    浏览量

    49129
  • 编译
    +关注

    关注

    0

    文章

    657

    浏览量

    32870

原文标题:#define和typedef的真正区别

文章出处:【微信号:strongerHuang,微信公众号:strongerHuang】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    C语言typedef与#define的用法和区别

    在C语言编程中,typedef 和 #define是最常用语句,可能很多工作过几年的工程师都没有去深究过它们的一些用法和区别
    发表于 10-12 10:39 682次阅读

    C语言#definetypedef区别

    在C语言编程中,typedef 和 #define是最常用语句,可能很多工作过几年的工程师都没有去深究过它们的一些用法和区别
    发表于 11-03 10:29 677次阅读

    第34集(7.2#100))typedef 与 #define,你确定你了解它们的差异?

    define
    于振南的单片机世界
    发布于 :2023年06月01日 23:38:40

    单片机中宏定义与重新定义数据类型(typedef区别

    单片机中宏定义与重新定义数据类型(typedef区别,并且各自的优势(初学单片机)eg:#define SKY unsigned chartypedef unsigned char SKY
    发表于 08-27 20:21

    C语言typedef和#define

    #define A inttypedef int BA a,b;B c,d;以上有错误吗,或者是否存在问题?若有错指出。
    发表于 03-08 19:42

    typedefdefine的用法与区别

    typedefdefine在一些用法上有一些相似之处,所以对于这方面接触不多的朋友可能会有所混淆,下面分享一个图,很清晰地对两者的用法作了区分。
    发表于 08-10 13:50

    typedef和#define区别

    关于自增自减(即++i,i++)typedef和#define区别static变量的三种用法static函数 —— 内部函数和外部函数
    发表于 02-05 07:56

    求助,关于C语言中的typedefdefine问题

    程序中typedef unsigned charUINT8和#define UINT8 unsigned char有什么特殊区别吗?不可以用一个来代替吗?为什么一个程序中要用两个?自己一直都是只用一个,没有涉及到用两个的情况,求
    发表于 10-26 06:30

    typedefdefine区别

    typedef是在计算机编程语言中用来为复杂的声明定义简单的别名,与宏定义有些差异。它本身是一种存储类的关键字define,无参宏定义的一般形式为:#define 标识符 字符串define
    发表于 11-09 14:22 6920次阅读
    <b class='flag-5'>typedef</b>和<b class='flag-5'>define</b><b class='flag-5'>区别</b>

    typedef struct的用法

    typedef是类型定义的意思。typedef struct 是为了使用这个结构体方便。具体区别在于:若struct node{ }这样来定义结构体的话。在定义 node 的结构体变量时,需要这样写:struct node n;
    发表于 11-09 17:20 3378次阅读

    typedefdefine的介绍及本质区别

    对于都可以用来给对象取一个别名的Typedefdefine来说,是有区别的。本文通过对typedefdefine的介绍,来给读者详细的讲
    发表于 04-14 07:31 5096次阅读

    C语言学习笔记---typedef 简介

       在单片机和操作系统中 typedef 会经常用到,它可以为某一个类型自定义名称。和#define比较类似。但是又有不同的地方。typedef 创建的符号只能用于数据类型,不能用于值。而
    发表于 01-13 13:26 1次下载
    C语言学习笔记---<b class='flag-5'>typedef</b> 简介

    C语言中的typedef的用法

    在以前的学习中对于C语言中typedefdefine的认识是,#define是宏,作用是简单的替换,而typedef也是替换,只不过比define
    发表于 01-13 13:36 0次下载
    C语言中的<b class='flag-5'>typedef</b>的用法

    typedef与#define有什么差异吗

    大部分朋友在编写代码的时候都会把无符号类型、结构体等等进行"简化",要么用宏定义进行文本替换,要么就通过typedef来定义一个类型别名。
    的头像 发表于 08-11 14:34 1364次阅读
    <b class='flag-5'>typedef</b>与#<b class='flag-5'>define</b>有什么差异吗

    typedef struct和直接struct的区别

    在C语言中, typedef 和 struct 是两种不同的关键字,它们在定义和使用上有着明显的区别typedef struct 和直接 struct 在 C 语言中用于定义结构体类型,但它们在
    的头像 发表于 08-20 10:58 2771次阅读