在总结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. Lua IDE

    http://blog.csdn.net/visualcatsharp/article/details/37653107

  2. 解决jeecg包升级之后无法启动的问题

    1.出现下述问题的解决办法. 解决包冲突问题,右键项目,选择properties 把lib目录下的jar吧添加上.remove调版本较低的包即可. 2. 解决方法,把jdk升级到1.7版本

  3. ClassNotFoundException: org.apache.catalina.loader.DevLoader 自己摸索,丰衣足食

    使用tomcat插件时遇到的问题: ClassNotFoundException: org.apache.catalina.loader.DevLoader 解决方案: 参考了许多文章,对我自己的目录 ...

  4. 面向科学计算的Python IDE--Anaconda

    1.下载 2.安装,假定路径为D:/Anaconda 3.在命令行中查看已安装的包及其版本 D: cd Anaconda conda list 结果: # packages in environmen ...

  5. runtime

    7.runtime实现的机制是什么,怎么用,一般用于干嘛. 你还能记得你所使用的相关的头文件或者某些方法的名称吗? 运行时机制,runtime库里面包含了跟类.成员变量.方法相关的API,比如获取类里 ...

  6. Canvas制作天气预报走势图

    要实现的效果如下图: HTML代码如下: ;;;;;;;;;;; }

  7. ffmpeg为视频添加时间戳 - 手动编译ffmpeg

    FFMPEG给视频加时间戳水印 项目中需要给视频添加时间戳,理所当然最好用的办法是ffmpeg.在找到正确的做法前,还被网上的答案timecode给水了一下(水的不轻,在这里转了2天),大概是这样写的 ...

  8. 高程(3):操作符、for、for...in循环、break/continue/return语句、函数等

    1.关系操作符 注意点:1)比较操作数是两个字符串,是比较字符串的字符编码值. 如:"a" > "b"  返回 false:"a" & ...

  9. java中 IndexOf()、lastIndexOf()、substring()的用法

    public int indexof(String str)返回字符串中出现str的第一个位置 public int indexof(String str,int fromIndex)返回字符串中从f ...

  10. php下载远程文件方法~

    直接上代码: getFile("http://easyread.ph.126.net/N8gDl6ayo5wLgKbgT21NZQ==/7917056565549478184.jpg&quo ...