C语言语法 typedef小结
在总结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小结的更多相关文章
- R语言语法基础一
R语言语法基础一 Hello world #这里是注释 myString = "hello world" print(myString) [1] "hello world ...
- Go语言语法说明
Go语言语法说明 go语言中的go func(){}() 表示以并发的方式调用匿名函数func 深入讲解Go语言中函数new与make的使用和区别 前言 本文主要给大家介绍了Go语言中函数new与ma ...
- PL真有意思(二):程序设计语言语法
前言 虽然标题是程序语言的语法,但是讲的是对词法和语法的解析,其实关于这个前面那个写编译器系列的描述会更清楚,有关语言语法的部分应该是穿插在整个设计当中的,也看语言设计者的心情了 和英语汉语这些自然语 ...
- Go语言语法汇总(转)
Go语言语法汇总 分类: 技术2013-09-16 14:21 3007人阅读 评论(0) 收藏 举报 go语言golang并发语法 目录(?)[+] 最近看了看GoLang,把Go语言的语法 ...
- C语言语法笔记 – 高级用法 指针数组 指针的指针 二维数组指针 结构体指针 链表 | IT宅.com
原文:C语言语法笔记 – 高级用法 指针数组 指针的指针 二维数组指针 结构体指针 链表 | IT宅.com C语言语法笔记 – 高级用法 指针数组 指针的指针 二维数组指针 结构体指针 链表 | I ...
- R语言语法基础二
R语言语法基础二 重塑数据 增加行和列 # 创建向量 city = c("Tampa","Seattle","Hartford"," ...
- L脚本语言语法手冊 0.10版
L脚本语言语法手冊 0.10版 简 介 L脚本语言是一个轻量级的,旨在接近自然语言的编程语言,眼下支持在中文.英文基础上的编程.并可扩展为随意语种.L脚本语言的语法结构简单.程序结构相对 ...
- 嵌入式C语言自我修养 01:Linux 内核中的GNU C语言语法扩展
1.1 Linux 内核驱动中的奇怪语法 大家在看一些 GNU 开源软件,或者阅读 Linux 内核.驱动源码时会发现,在 Linux 内核源码中,有大量的 C 程序看起来“怪怪的”.说它是C语言吧, ...
- 【Introduction】R语言入门关键小结
写在前面:本博客为本人原创,严禁任何形式的转载!本博客只允许放在博客园(.cnblogs.com),如果您在其他网站看到这篇博文,请通过下面这个唯一的合法链接转到原文! 本博客全网唯一合法URL:ht ...
随机推荐
- 小程序和APP谁将主导未来?
APP和小程序的未来会怎么样?小程序的出现真的会加速APP的灭亡吗?今天这篇文章,是对小程序和App未来发展格局的一些思考,更多的是想提醒各位拥抱小程序的的参与者,我们在决定参与这场狂欢的同时,切勿盲 ...
- http执行过程分析
执行过程: 1.用户在浏览器(客户端)里输入或者点击一个网址链接: 2.浏览器通过网址域名查找ip地址.DNS查找方式是通过浏览器缓存(会记录DNS记录)→系统缓存→TCP/IP参数中设置的首选DNS ...
- MyBatis源码分析(5)——内置DataSource实现
@(MyBatis)[DataSource] MyBatis源码分析(5)--内置DataSource实现 MyBatis内置了两个DataSource的实现:UnpooledDataSource,该 ...
- todo
ID生成器要做成兼容分布式, 数据库ef控制要改成手动升级, 异常日志模块,操作日志某快,,, 日志服务器,, 图片服务器,,,动静分离, 前后台分离,, 可扩展性,无状态化集群弹性部署, 数据库主 ...
- html5中画布和SVG的比较
SVG是基于XML的图形语言,在DOM解析中其每个元素都是可以用的,这样就可以为SCG元素附加JavaScript事件处理器,实现更加丰富的效果. 在SVG中,每个被绘制的图形均被视为对象,如果SVG ...
- 利用AOP与ToStringBuilder简化日志记录
刚学spring的时候书上就强调spring的核心就是ioc和aop blablabla...... IOC到处都能看到...AOP么刚开始接触的时候使用在声明式事务上面..当时书上还提到一个用到ao ...
- js 查找树节点 数组去重
//查找树节点function findData(curOrg, id) { var array = []; if ((typeof curOrg == 'object') && (c ...
- MAC OS升级到10.11(OS X EICAPTION)之后CocoaPods不能正常使用的问题解决
昨晚回家之后开始升级系统到10.11,下载了一整个晚上之后终于在早上下载完毕,早上带到公司,想查一个第三方库的时候却遇到了问题: guoyufudeMacBook-Pro:~ GuoYufu$ pod ...
- Workflow 中做拒绝操作时强制输入拒绝信息
在做AP发票审批驳回时,客户要求必须强制输入拒绝原因,代码如下: PROCEDURE Validate_Response ( Itemtype IN VARCHAR2, Itemkey IN VARC ...
- 释放修改OS X 10.11系统文件权限【转】
序言:有时要替换相关的(系统目录下的)文件以完成软件的破解,但在 OS X 10.11 系统图形界面下,Root(系统超级用户)已‘转变’为 Administrator(管理员用户),选择系统文件夹( ...