最近在复习数据结构时,经常看到 typedef 的身影,但始终不清楚 typedef 的用法具体时怎么样的,特地查阅《C Primer Plus 第5版》,并将查到的内容写出来供大家沟通学习。

typedef 工具是一种高级数据特性,它使你能够为某一类型创建您自己的名字。在这个方面,它和 #define 相似,但是它们具有3个不同之处:

  • 与 #define 不同,typedef 给出的符号名称仅限于对类型,而不是对值。
  • typedef 的解释由编译器,而不是由解释器执行。
  • 虽然它的范围有限,但在受限范围内,typedef 比 #define 更灵活。

我们来看看 typedef 是怎样工作的。假设要对1字节的教值使用术语BYTE,您只须像定义一个char变量那样定义BYTE,然后在这个定义前面加上关健字 typedef,如:

typedef unsigned char BYTE;

随后您就可以使用 BYTE 来定义变量了:

BYTE x, y[], *z;

该定义的作用域取决于 typedef 语句所在的位置。如果定义是在一个函数内部,它的作用域就县局部的,限定在那个函数里。如果定义是在函教外部,它将具有全局作用域。

通常,这些定义使用大写字母,以提醒用户这个类型名称实际上是个符号缩写。不过,您也可以使用小写字母:

typedef unsigned char byte;

管理变量名的同样规则也用来管理 typedef 使用的名字。

为一个已经存在的类型创建一个名字可能看起来没有什么必要,然而这可能会是有用的。在前面的例子中,使用BYTE来代替 unsigned char 有助于说明您打算用 BYTE 变量来表示数值而非字符编码。使用 typedef 也有助于增加可移植性。例如,我们已经提到过表示 sizeof 运算符返回类型的size_t 类型,以及表示函数 time() 的返回值类型的 time_t 类型。C标准规定 sizeof 和 time() 应返回整数类型,但它留给具体的实现来决定到底是哪种整数类型。不进行指定的原因是ANSI C委员会觉得没有一个对所有计算机平台来说都是最好的选择。因此他们提出一个新类型名称,如 time_t,让C实现使用 typedef 来把这个名称设定为某种特定的数据类型。这样,他们可以提供下列通用原型:

time_t time(time_t *);

在一个系统上,time_t 可能是 unsigned int 类型;在另一个系统上,它可能是 unsigned long 类型。只要包含了 time.h 头文件,程序就可以访问适当的定义,您也可以在代码中声明 time_t 变量。

使用 #define 可以实现 typedef 的部分功能。例如:

#define BYTE unsigned char

这使预处理器用 unsigned char来代替 BYTE。但也有 #define 实现不了的功能,如下例所示:

typedef char* STRING;

如果没有关键字 typedef,该例将 STRING 识别为一个 char 指针。有了这个关键字,使STRING成为 char 指针的标识符。因此:

STRING name, sign;

意思是:

char * name, * sign;

但是,假设这样做:

#define STRING char *;

那么:

STRING name, sign;

将会被翻译成下面的形式:

char *name,sign;

在这种情况下,只有 name 是一个指针。

也可以对结构使用 typedef:

typedef struct complex{
float real;
float imag;
}COMPLEX;

这样您就可以用类型 COMPLEX 代替 struct complex 来表示复数。使用 typedef 的原因之一是为经常出现的类型创建一个方便的、可识别的名称。例如,在前面的例子中,许多人都愿意使用 STRING 或与其等价的标记。

使用 typedef 来命名一个结构类型时,可以省去结构的标记:

typedef struct{
double x;
double y;
}rect;

假设像下面这样使用 typedef 定义的类型名:

rect r1 = {3.0, 6.0};
rect r2;
r2 = r1;

这被翻译成:

 struct{
double x;
double y;
}r1 = {3.0, 6.0}; struct{
double x;
double y;
}r2;
r2 = r1;

如果两个结构的声明都不使用标记,但是使用同样的成员(成员名和类型鄯匹配),那么 C 认为这两个结构具有同样的类型,因此将 r1 赋给 r2 是一个正确的操作。

使用 typedef 的另一个原因是 typedef 的名称经常被用于复杂的类型。例如:

typedef char (* FRPTC ()) [5];

这把 FRPTC 声明为一个函数类型,该类型的函数返回一个指向含有5个元素的 char 数组的指针(请参见下面将要讨论的一些奇特的声明)。

当使用 typedef 时,要记住它并不创建新的类型,它只是创建了便于使用的标签。这意味著,例如,我们创建的 STRING 关型的安量可以作为参数传递给需要 char 指针类型参数的函数。

通过结构、联合和 typedef,C 提供了有效和方便地处理数据的工具。

作者:耑新新,发布于  博客园

转载请注明出处,欢迎邮件交流:zhuanxinxin@aliyun.com

说说 typedef 的那些事的更多相关文章

  1. typedef与define

    一.typedef用法 typedef常用来定义一个标识符及关键字的别名,它生效是在语言编译过程,但它并不实际分配内存空间.typedef可以增强程序的可读性,以及标识符的灵活性,但它也有“非直观性” ...

  2. typedef函数指针那些事

    首先来介绍下函数指针: 函数指针是指向函数的指针变量,即本质是一个指针变量. int (*f) (int x); /* 声明一个函数指针 */ f=func; /* 将func函数的首地址赋给指针f ...

  3. C++的那些事:数据与类型

    一.前言 最近在看C++Primer第5版,先前已经看过第4版,但是发现第5版在整个知识布局与个别知识的讲解上跟第4版差别还是挺大的,尤其是新增了C++11的内容,正如孟岩老师在第5版前言中所讲:“现 ...

  4. c语言 typedef

      在C和C++编程语言中,typedef是一个关键字.它用来对一个资料类型取一个新名字.目的是为了使源代码更易于阅读和理解. 来看以下程式码: int coxes; int jaffa; ... c ...

  5. C语言--enum,typedef enum 枚举类型详解

    原文:http://z515256164.blog.163.com/blog/static/32443029201192182854300/ 有改动 C语言详解 - 枚举类型 注:以下全部代码的执行环 ...

  6. 由typedef和函数指针引起的危机

    由typedef和函数指针引起的危机 昨天阅读了大神强哥的代码,发现里面用到了函数指针,也用到的typedef.本来我自以为对这两个概念有一定的认识,但是突然发现这两个东西居然用到了一起!!!!(在一 ...

  7. 痞子衡嵌入式:飞思卡尔Kinetis系列MCU启动那些事(11)- KBOOT特性(ROM API)

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是飞思卡尔Kinetis系列MCU的KBOOT之ROM API特性. KBOOT的ROM API特性主要存在于ROM Bootloader ...

  8. Item 9: 比起typedef更偏爱别名声明(alias declaration)

    本文翻译自modern effective C++,由于水平有限,故无法保证翻译完全正确,欢迎指出错误.谢谢! 博客已经迁移到这里啦 我确信我们都同意使用STL容器是一个好主意,并且我希望在Item ...

  9. COGS 1224. [SHOI2002]百事世界杯之旅(期望概率)

    COGS 1224. [SHOI2002]百事世界杯之旅 ★   输入文件:pepsi.in   输出文件:pepsi.out   简单对比 时间限制:1 s   内存限制:128 MB [问题描述] ...

随机推荐

  1. CubeSuit+ ( CS+ for ca )

    作为瑞萨单片机的初学者,最先接触的当属它的IDE了,接下来我将分享一些我使用这款单片机的心得,以供大家参考. 我使用的是RL78F13系列R5F10BGE,那如何建立一个能使用的工程呢?相信大家在网络 ...

  2. SuperSocket 最基础入门

    ---恢复内容开始--- SuperSocket 是什么? 首先我们明确一下SuperSocket 本质是什么? 网络框架 !  ok , 那么我们直接上上官网,作者已经开源到Github,可以做两件 ...

  3. [C#]使用Quartz.NET来创建定时工作任务

    本文为原创文章.源代码为原创代码,如转载/复制,请在网页/代码处明显位置标明原文名称.作者及网址,谢谢! 开发工具:VS2017 语言:C# DotNet版本:.Net FrameWork 4.0及以 ...

  4. PHP-无限级分类

    给定省市地区数组如下: $area = array(                   array('id'=>1,'name'=>'安徽','parent'=>'0'),     ...

  5. userdel 命令详解

    userdel  作用: 删除指定用户,以及用户相关的文件. 如不加选项,则仅删除用户账号,而不删除相关文件 选项: -f:强制删除用户,即时用户当前已登录 -r:删除用户的同时删除与用户相关的所有文 ...

  6. Python:监控ASM剩余空间

    #!/usr/bin/env python # -*- coding:utf-8 -*- __author__ = 'Jipu FANG' version = 0.1 import cx_Oracle ...

  7. MySQL Replication 主从复制全方位解决方案

    1.1 主从复制基础概念 在了解主从复制之前必须要了解的就是数据库的二进制日志(binlog),主从复制架构大多基于二进制日志进行,二进制日志相关信息参考:http://www.cnblogs.com ...

  8. thinkphp3.2.3使用ajax 的一些坑——使用AjaxReturn()后,直接返回null,模板文件不起作用

    从接触thinkphp到今天,填完此坑,必有其他的坑有会冒出来.哎!这个填坑之路我想是没有尽头的了. 最近,需要使用ajax完成一些操作,一开始想Ajax简单啊,不过是一种提交数据的方式,不过是害苦了 ...

  9. 使用Word进行文档修订版本的比较

    项目经理在实际的工作过程中,比如要写文档方案,就需要对文档的修订版本进行管理和控制.在以前的工作中,笔者使用的是UltraEdit这个软件工具中的Ultra Compare这个子工具来进行的文档版本的 ...

  10. 怎么制作html5网站页面让它适应电脑和手机的尺寸

    https://zhidao.baidu.com/question/918130826792192539.html 用以下代码开头:<!DOCTYPE HTML><html>& ...