在总结typedef之前,先了解一个专业术语:

常量指针(const pointer):常量指针在定义的时候必须被初始化,而且一旦初始化完成,则它的值就不能再改变。

int errNumb = 0;
int *const curErr = &errNumb; // curErr将一直指向errNumb,不可以改变。
1.typede是什么。

类型别名(type alias)是一个名字,它是某种类型的同义词。使用类型别名有很多好处,它可以让复杂的类型名字变得简单明了、易于理解和使用,还有助于程序员清楚地知道使用该类型的真实目的。

传统的方法是使用关键字typedef:

typedef double wages;    // wages是double的同义词
typedef wages base, *p; // base是double的同义词,p是double *的同义词

其中,关键字typedef作为声明语句中的基本类型的一部分出现。含有typedef的声明语句定义的不再是变量而是类型别名。和以前的普通基本类型声明一样,这里的声明也可以包含类型修饰,从而也能由基本类型构造出符合类型来。

2.如何理解使用typedef来给基本数据类型起一个别名。

如果某个类型别名指代的是复合类型或常量,那么,把它用到声明语句里就会产生意想不到的后果。例如下面的声明语句用到了类型pstring,它实际上是类型char*的别名:

typedef char *pstring;
const pstring cstr = 0; // cstr是指向char的常量指针
const pstring *ps; // ps是一个指针,它的对象是指向char的常量指针

上述两条声明语句的基本数据类型都是const pstring,和过去一样,const是对给定的类型的修饰。pstring实际上是指向char的指针,因此,const pstring就是指向char的常量指针,而非指向常量字符的指针。

遇到一条使用了类型别名的声明语句时,人们往往会错误地尝试把类型别名替换成它本来的样子,以理解该语句的含义:

const char *cstr = 0;    // 是对const pstring cstr的错误理解

再强调一遍:这种理解是错误的。声明语句中用到pstring时,其基本数据类型是指针。可是用char重写了声明语句后,数据类型就变成了char, 而成为了声明符的一部分。这样的改写显然是错误的。这样改写的结果是,const char 成了基本数据类型。前后两种声明含义截然不同,前者声明了一个指向char的常量指针,改写后的形式则声明了一个指向const char的普通指针。

我写的测试代码如下:

#include <stdio.h>

typedef char *pstring;

int main(char argc, char *argv[]) {
char a = 'h', b = 'f';
pstring cstr = NULL;
const char *t = NULL;
cstr = &a;
const pstring pa, pb = &b;
t = &a;
pa = &a; // compile error: assignment of read-only variable 'pa' printf("hello world\n");
return 0;
}
3.如何理解typedef给函数指针类型起一个别名。

在我们平时写代码的过程中,我们虽然不能定义一个函数类型的行参,但是行参可以是指向函数的指针。此时,行参看起来是函数类型,实际上却是当成指针使用:

// 第三个行参是函数类型,它会自动转换成指向函数的指针
void useBigger(const char *s1, const char *s2,
bool pf(const char *, const char *));
// 等价的声明:显式地将行参定义成指向函数的指针
void useBigger(const char *s1, const char *s2,
bool (*pf)(const char *, const char *));

我们可以直接把函数作为实参使用,此时它会自动转换成指针:

// 自动将函数函数lengthCompare转换成指向该函数的指针

useBigger(s1, s2, lengthCompare);

正如useBigger的声明语句所示,直接使用函数指针类型显得冗长而繁琐。我们可以通过typedef来加以简化使用了函数指针的代码:

// Func是函数类型
typedef bool Func(const char *, const char *); // FuncP是指向函数的指针
typedef bool (*FuncP)(const char *, const char *);

我们使用typedef定义自己的类型。Func是函数类型,而FuncP是指向Func类型函数(函数原型,形如Func)的指针类型。

参考:

《C++Primer中文第5版》:Page56,60,61,222

C语言语法 typedef小结的更多相关文章

  1. R语言语法基础一

    R语言语法基础一 Hello world #这里是注释 myString = "hello world" print(myString) [1] "hello world ...

  2. Go语言语法说明

    Go语言语法说明 go语言中的go func(){}() 表示以并发的方式调用匿名函数func 深入讲解Go语言中函数new与make的使用和区别 前言 本文主要给大家介绍了Go语言中函数new与ma ...

  3. PL真有意思(二):程序设计语言语法

    前言 虽然标题是程序语言的语法,但是讲的是对词法和语法的解析,其实关于这个前面那个写编译器系列的描述会更清楚,有关语言语法的部分应该是穿插在整个设计当中的,也看语言设计者的心情了 和英语汉语这些自然语 ...

  4. Go语言语法汇总(转)

    Go语言语法汇总 分类: 技术2013-09-16 14:21 3007人阅读 评论(0) 收藏 举报 go语言golang并发语法   目录(?)[+]   最近看了看GoLang,把Go语言的语法 ...

  5. C语言语法笔记 – 高级用法 指针数组 指针的指针 二维数组指针 结构体指针 链表 | IT宅.com

    原文:C语言语法笔记 – 高级用法 指针数组 指针的指针 二维数组指针 结构体指针 链表 | IT宅.com C语言语法笔记 – 高级用法 指针数组 指针的指针 二维数组指针 结构体指针 链表 | I ...

  6. R语言语法基础二

    R语言语法基础二 重塑数据 增加行和列 # 创建向量 city = c("Tampa","Seattle","Hartford"," ...

  7. L脚本语言语法手冊 0.10版

    L脚本语言语法手冊 0.10版       简  介 L脚本语言是一个轻量级的,旨在接近自然语言的编程语言,眼下支持在中文.英文基础上的编程.并可扩展为随意语种.L脚本语言的语法结构简单.程序结构相对 ...

  8. 嵌入式C语言自我修养 01:Linux 内核中的GNU C语言语法扩展

    1.1 Linux 内核驱动中的奇怪语法 大家在看一些 GNU 开源软件,或者阅读 Linux 内核.驱动源码时会发现,在 Linux 内核源码中,有大量的 C 程序看起来“怪怪的”.说它是C语言吧, ...

  9. 【Introduction】R语言入门关键小结

    写在前面:本博客为本人原创,严禁任何形式的转载!本博客只允许放在博客园(.cnblogs.com),如果您在其他网站看到这篇博文,请通过下面这个唯一的合法链接转到原文! 本博客全网唯一合法URL:ht ...

随机推荐

  1. 移动开发框架剖析(二) Hammer专业的手势控制

    浏览器底层并没有给元素提供类似,单击,双击,滑动,拖动这些直接可以用的控制接口,一切的手势动作都只能通过模拟出来.移动端浏览器唯一给我们提供的就只是mousedown -> mousemove ...

  2. REDHAT一总复习1 ssh配置 禁用root用户SSH连接

    生成SSH公钥 $ ssh-keygen 生成的公钥安装到指定的服务器上,这里安装到desktop0上的student账户 $ ssh-copy-id desktop0 $ su - 禁用root用户 ...

  3. shell test用法

    1)判断表达式 if test  (表达式为真) if test !表达式为假 test 表达式1 –a 表达式2                  两个表达式都为真 test 表达式1 –o 表达式 ...

  4. ASP.NET 验证码控件

    public class ValidateCode : WebControl { /// <summary> /// 默认构造函数,暴露的属性接口 /// </summary> ...

  5. 爬取https页面遇到“SSLError: hostname 'xxx' doesn't match either of”的解决方法

    使用python requests 框架包访问https://itunes.apple.com 页面是遇到 SSLError: hostname 'itunes.apple.com' doesn't ...

  6. java基础知识(十一)java反射机制(下)

    1.什么是反射机制? java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法,对于任意一个对象都能够调用他的属性和方法,这种动态获取属性和方法的功能称为java的反射机制. ...

  7. UIAlertController

    楼主在整理项目的警告,于是乎你懂的. 然后自己整理了一下以后方便自己忘了之后能及时找到它 关于UIAlertController .h文件的解析 /** 关于UIAlertController的解析 ...

  8. spring 参数绑定

    部分资料来源: @RequestParam @RequestBody @PathVariable 等参数绑定注解详解 spring学习之@ModelAttribute运用详解 Spring MVC @ ...

  9. ubuntu 16.04安装docker

    环境 操作系统:ubuntu 16.04 64位,默认安装 准备 1. 添加GPG key: $ sudo apt-key adv --keyserver hkp://p80.pool.sks-key ...

  10. tengine/nginx-tomcat动静分离遇到的问题

    小站安装好tengine后,接下来的工作就是要配置好tengine让其和后端的tomcat正常的连接工作起来,tengine的配置文件本身比较简单,网上有大量的相关介绍说明文档,我这里只是摘出我配置过 ...