在单片机和操作系统中 typedef 会经常用到,它可以为某一个类型自定义名称。和#define比较类似。但是又有不同的地方。

  • typedef 创建的符号只能用于数据类型,不能用于值。而#define 创建的符号可以用于值。
  • typedef 是由编译器来解释,而不是预处理器。
  • typedef 使用起来更加灵活。

  下面使用typedef定义一个数据类型

int main()
{typedef unsigned char BYTE;    BYTE c = 10;   printf("%d \r\n",c);system("pause");return 0;
}

  使用typedef将unsigned char类型重新定义为BYTE类型,然后在使用新的类型BYTE定义一个变量c。输出结果如下:

  此时如果使用 #define 来替换,好像也可以。

  这里使用 #define 将unsigned char替换为 BYTE好像也正确。

  下面在看一个例子。

int main()
{typedef char * STR;        STR s1,s2;  s1="abc";s2="123";        printf("%s %s \r\n",s1,s2);   system("pause");return 0;
}

  将字符指针 char * 重新定义为STR类型,然后使用STR定义两个指针s1和s2,这样s1和s2都是指向字符的指针。接着给这两个指针赋值,然后打印出来。

  这时使用 #define 来替换 typedef 的功能。

#define STR  char *
int main()
{STR s1,s2; s1="abc";s2="123";    printf("%s %s \r\n",s1,s2);   system("pause");return 0;
}

  这时候编译程序的时候,程序会报错。

  这时为什么呢?因为使用typedef的时候,是定义了一个新的数据类型。

typedef char * STR;
STR s1,s2;

相当于

char *s1, *s2;
s1="abc";
s2="123";

s1和s2都是指向字符类型的指针。

  如果使用 #define 的时候,系统只是简单的替换。

#define STR  char *
STR s1,s2;

将STR用 char * 进行替换

 char *s1,s2;    s1="abc";s2="123";

  替换后只有s1是指针,s2依然是一个char类型的变量。所以给s2赋值一个字符串的时候系统就会报错。因此要重新定义一个数据类型的时候,要使用typedef,这个在定义结构体的时候使用的非常多。

typedef struct Date
{int year;int month;int day;
} DT;

  使用typedef 将结构体 struct Date 重新定义为DT类型,这样在使用DT定义变量的时候,就相当于使用了 struct Date 来定义变量。

typedef struct Date
{int year;int month;int day;
} DT;DT d1 = {2021,10,1};
DT d2 = {2021,10,10};

等价于

struct Date
{int year;int month;int day;
};
struct Date d1 = {2021,10,1};
struct Date d2 = {2021,10,10};

  这样通过使用 typedef 来重新定义一个新的类型,使代码写起来更加的简洁。这种方法在单片机的库函数中使用的最多。

typedef struct
{uint16_t GPIO_Pin;          GPIOSpeed_TypeDef GPIO_Speed; GPIOMode_TypeDef GPIO_Mode;
}GPIO_InitTypeDef;void LED_Init(void)
{ GPIO_InitTypeDef  GPIO_InitStructure;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;                          //LED0-->PA8 端口配置GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;         //推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;        //IO口速度为50MHzGPIO_Init(GPIOA, &GPIO_InitStructure);                                   /PD2 输出高
}

  通过 typedef 将结构体重定义为GPIO_InitTypeDef 类型,这样在初始化的时候,直接使用GPIO_InitTypeDef 类型就可以定义一个关于GPIO的结构体。

  在定义数据类型的时候,也会用到 typedef 重新定义一个数据类型。

  通过tepedef 定义新的数据类型,增加了代码的可读性和移植性。这里说的新的数据类型不是创建了一个系统不存在的数据类型,而是给已经存在的某个类型增加了一个方便使用的标签。而这个标签又不同于 #define 只是简单的符号替换。

C语言学习笔记---typedef 简介相关推荐

  1. C语言学习笔记——typedef

    Typedef typedef为C语言的关键字,作用是为一种数据类型定义一个新名字,这里的数据类型包括内部数据类型(int,char等)和自定义数据类型(struct等),和strucut来匹配使用为 ...

  2. 梓益C语言学习笔记之链表&动态内存&文件

    梓益C语言学习笔记之链表&动态内存&文件 一.定义: 链表是一种物理存储上非连续,通过指针链接次序,实现的一种线性存储结构. 二.特点: 链表由一系列节点(链表中每一个元素称为节点)组 ...

  3. go get 拉取指定版本_go语言学习笔记-基础知识-3

    相关文档 go语言学习笔记-目录 1.简介 1.1 什么是GO Go 是一个开源的编程语言,它能让构造简单.可靠且高效的软件变得容易.Go是从2007年末由Robert Griesemer, Rob ...

  4. c语言如何宏定义枚举型结构体,C语言学习笔记--枚举结构体

    枚举 枚举是一种用户定义的数据类型,它用关键字enum以如下语法格式来声明: enum 枚举类型名字 {名字0,名字1,...,名字n}: 枚举类型名字通常并不真的使用,要用的是大括号里面的名字,因为 ...

  5. c语言存储类型关键字作用,c语言学习笔记.关键字.存储类型关键字等

    关键字const 1.修饰变量. 修饰的对象为常量,只读. 2.修饰指针. const 也可以和指针变量一起使用,这样可以限制指针变量本身,也可以限制指针指向的数据. const 离变量名近就是用来修 ...

  6. R语言学习笔记——入门篇:第一章-R语言介绍

    R语言 R语言学习笔记--入门篇:第一章-R语言介绍 文章目录 R语言 一.R语言简介 1.1.R语言的应用方向 1.2.R语言的特点 二.R软件的安装 2.1.Windows/Mac 2.2.Lin ...

  7. C语言学习笔记10-指针(动态内存分配malloc/calloc、realloc、释放free,可变数组实现;Tips:返回指针的函数使用本地变量有风险!;最后:函数指针)

    C语言:指针 1. 指针:保存地址的变量 *p (pointer) ,这种变量的值是内存的地址.   取地址符& 只用于获取变量(有地址的东西)的地址:scanf函数-取地址符   地址的大小 ...

  8. C语言学习笔记06-占位符格式、C基本类型及逃逸字符一些细节(附介绍BCD码)

    主要整理有关占位符格式与逃逸字符的一些细节 朋友们,看栗子--"BCD解码" (文末附BCD码介绍) 一个BCD数的十六进制是0x12(对应二进制表示:0001 0010),它表达 ...

  9. 史上最全C语言学习笔记

    最全C语言学习笔记 学习目标 学习编程最主要目标 分析问题的能力.构造算法的能力.编程的能力. 调试程序的能力. 学习方法手段 如何操作? 解题思路:重点要放在解题的思路上 一开始就要学会看懂程序,编 ...

最新文章

  1. Symantec Endpoint - quarantine
  2. Android - could not install *smartsocket* listener
  3. 取得前九条之后的数据
  4. Lecture Halls
  5. 如何在Web应用程序中使用TWAIN驱动程序的自定义功能?
  6. 算法——贝叶斯公式的推导过程
  7. IO多路复用的机制:select、poll、epoll
  8. LNMP详解(十二)——Nginx URL重写实战
  9. Zeppelin求学之路(3)—Zeppelin基本模块介绍和Paragraph源码深入了解以及Note,NoteBook 简介,
  10. Spring - 关于IOC和DI的一些个人理解
  11. linux boot efi 大小,/boot/efi。
  12. 详解p=q->next和p->next=q的区别,附代码
  13. mysql evict_SpringBoot+Mybatis+MySQL实现读写分离
  14. 什么是复制和交换成语?
  15. 今天出门你查老黄历了吗?包括万年历在内的超多免费可用 API 推荐(一)
  16. 二代测序的原理和简介
  17. 轻松6步教您掌握TeeChart图表控件绘图攻略
  18. SWUST OJ 971求二叉树的深度
  19. 来自谷歌大脑的SpineNet:一种非常规的主干结构
  20. 守护进程--day33

热门文章

  1. vcneter5.5添加域用户权限
  2. 可用于Asp.net的嵌入式数据库SqlCE4.0试用笔记
  3. HUB,交换机,路由器,MODEM都有什么区别???
  4. 【转】Android-Input 按键字符映射文件输入设备配置文件
  5. .Net Core 商城微服务项目系列(一):使用IdentityServer4构建基础登录验证
  6. 设置eclipse的Maven插件引入依赖jar包后自动下载并关联相应的源码(转)
  7. 抛物线、导弹线轨迹计算
  8. frisby用例动态链
  9. Java Web项目 配置 ueditor心得
  10. Java反射在Main方法的中的而应用