再谈typedef(重点为函数指针)

2009-09-17 10:15:43|  分类: linux学习 |字号 订阅

有种很方便的写法。

typedef int *p;

p pointer;

这时直接把pointer带入原式中,取代p然后去掉typedef,得到的结果就是int * pointer;

哈哈,这样直接替换就很直观多了。

C语言语法简单,但内涵却博大精深;如果在学习时只是止步于表面,那么往往后期会遇到很多困 难。typedef是C语言中一个很好用的工具,大量存在于已有代码中,特别值得一提的是:C++标准库实现中更是对typedef有着大量的使用。但很 多初学者对其的理解仅局限于:typedef用来定义一个已有类型的"别名(alias)"。正是因为有了这样的理解,才有了后来初学者在typedef int myint和typedef myint int之间的犹豫不决。很多国内大学的C语言课之授课老师也都是如是说的,或者老师讲的不够透彻,导致学生们都是如是理解的。我这里想结合C语言标准文档 以及一些代码实例,也说说typedef。

int    *p;

这样的代码是C语言中最最基础的一个语句了,大家都知道这个语句声明了一个变量p,其类型是指向整型的指针(pointer to int);如果在这个声明的前面加上一个typedef后,整个语义(semantics)又会是如何改变的呢?

typedef  int    *p;

我们先来看看C99标准中关于typedef是如何诠释的?C99标准中这样一小段精辟的描 述:"In a declaration whose storage-class specifier is typedef, each declarator defines an identifier to be a typedef name that denotes the type specified for the identifier in the way described in xx"。

参照这段描述,并拿typedef  int    *p作为例子来理解:在一个声明中,如果有存储类说明符typedef的修饰,标识符p将被定义为了一个typedef name,这个typedef name表示(denotes)一个类型,什么类型呢?就是int *p这个声明(declarator)中标识符(indentifier)p的类型(int*)。

再比对一下两个声明:

int    *p;

typedef  int    *p;

是不是有点"茅舍顿开"的感觉,int *p中, p是一个变量,其类型为pointer to int;在int *p前面增加一个typedef后,p变为一个typedef-name,这个typedef-name所表示的类型就是int *p声明式中p的类型(int*)。说句白话,typedef让p去除了普通变量的身份,摇身一变,变成了p的类型的一个typedef-name了。

为了巩固上面的理解,我们再来看看"C语言参考手册(C: A Reference Manual)"中的说法:任何declarator(如typedef int   *p)中的indentifier(如p)定义为typedef-name, 其(指代p)表示的类型是declarator为正常变量声明(指代int  *p)的那个标识符(指代p)的类型(int*)。有些绕嘴,不过有例子支撑:

[例1]

typedef double MYDOUBLE;

分析:

去掉typedef ,得到正常变量声明=> double MYDOUBLE;

变量MYDOUBLE的类型为double;

=> "typedef double MYDOUBLE"中MYDOUBLE是类型double的一个typedef-name。

MYDOUBLE    d; <=> d是一个double类型的变量

[例2]

typedef double *Dp;

分析:

去掉typedef  ,得到正常变量声明=> double *Dp;

变量Dp的类型为double*,即pointer to double;

=> "typedef double *Dp"中Dp是类型double*的一个typedef-name。

Dp    dptr; <=> dptr是一个pointer to double的变量

[例3]

typedef int* Func(int);

分析:

去掉typedef  ,得到正常变量声明=> int* Func(int);

变量Func的类型为一个函数标识符,该函数返回值类型为int*,参数类型为int;

=> "typedef int* Func(int)"中Func是函数类型(函数返回值类型为int*,参数类型为int)的一个typedef-name。

Func    *fptr; <=> fptr是一个pointer to function with one int parameter, returning a pointer to int

Func     f;   这样的声明意义就不大了。

[例4]

typedef int (*PFunc)(int);

分析:

去掉typedef  ,得到正常变量声明=> int (*PFunc)(int);

变量PFunc的类型为一个函数指针,指向的返回值类型为int,参数类型为int的函数原型;

=> "typedef int (*PFunc)(int)"中PFunc是函数指针类型(该指针类型指向返回值类型为int,参数类型为int的函数)的一个typedef-name。

PFunc     fptr; <=> fptr是一个pointer to function with one int parameter, returning int

#include "iostream"

using namespace std;

int add(int a,int b){
return (a+b);
}

typedef int (* func)(int ,int ) ;

void main(){
func f = add;
int n = f(1,2);
cout << n << endl;
}

[例5]

typedef    int   A[5];

分析:

去掉typedef ,得到正常变量声明 => int   A[5];

变量A的类型为一个含有5个元素的整型数组;

=> "typedef    int   A[5]"中A是含有5个元素的数组类型的一个typedef-name。

A   a = {3, 4, 5, 7, 8};

A   b = { 3, 4, 5, 7, 8, 9}; /* 会给出Warning: excess elements in array initializer */

[例6]

typedef    int   (*A)[5]; (注意与typedef    int*    A[5]; 区分)

分析:

去掉typedef ,得到正常变量声明 => int   (*A)[5];

变量A的类型为pointer to an array with 5 int elements;

=> "typedef    int   (*A)[5]"中A是"pointer to an array with 5 int elements"的一个typedef-name。

int   c[5] = {3, 4, 5, 7, 8};

A    a = &c;

printf("%d\n", (*a)[0]); /* output: 3 */

如果这样赋值:

int   c[6] = {3, 4, 5, 7, 8, 9};

A    a = &c; /* 会有Warning: initialization from incompatible pointer type */

[例7]

typedef struct _Foo_t Foo_t;

分析:

去掉typedef ,得到正常变量声明 => struct _Foo_t Foo_t;

变量Foo_t的类型为struct _Foo_t;

=> "typedef struct _Foo_t Foo_t"中Foo_t是"struct _Foo_t"的一个typedef-name。

[例8]

typedef   struct { ... // }   Foo_t;

分析:

去掉typedef ,得到正常变量声明 => struct { ... // }   Foo_t;

变量Foo_t的类型为struct { ... // } ;

=> "typedef   struct { ... // }   Foo_t "中Foo_t是"struct { ... // }"的一个typedef-name。这里struct {...//}是一个无"标志名称(tag name)"的结构体声明。

参考资料:

1、"ISOIEC-98991999(E)--Programming Languages--C"之Page 123;

2、C语言参考手册(中文版) 之 Page 119

转载于:https://www.cnblogs.com/artstyle/archive/2012/03/30/2425750.html

typedef 用法总结相关推荐

  1. typedef用法小结

    Typedef 声明有助于创建平台无关类型,甚至能隐藏复杂和难以理解的语法.不管怎样,使用 typedef 能为代码带来意想不到的好处,通过本文你可以学习用 typedef 避免缺欠,从而使代码更健壮 ...

  2. 关于C++中函数指针的使用(包含对typedef用法的讨论)

    关于C++中函数指针的使用(包含对typedef用法的讨论) (一)简单的函数指针的应用. //形式1:返回类型(*函数名)(参数表) char (*pFun)(int); char glFun(in ...

  3. typedef用法(1)

    Typedef 声明有助于创建平台无关类型,甚至能隐藏复杂和难以理解的语法.不管怎样,使用 typedef 能为代码带来意想不到的好处,通过本文你可以学习用 typedef 避免缺欠,从而使代码更健壮 ...

  4. typedef 用法详解

    第一部分 基本概念 1.基本解释 typedef为C语言的关键字,作用是为一种数据类型定义一个新名字.这里的数据类型包括内部数据类型(int,char等)和自定义的数据类型(struct等). 在编程 ...

  5. C和C++中struct的typedef用法建议

    C和C++中struct的typedef用法建议 参考文章(建议先读) 根据参考的文章,总结一下: 情况1 C语言中: typedef struct{ ···: }aaa; 则aaa是struct类的 ...

  6. Typedef用法(转载)

    在C的学习过程中,现在才发现,以前有那么多被忽略的重点:现在是慢慢拾起这些重点的时候,通过百度和博客,我感觉我学到了很多东西,自己只是在别人说的基础上,按照自己学习的过程在这里记录一下,以后有时间回过 ...

  7. Typedef用法学习

    不管实在C还是C++代码中,typedef这个词都不少见,当然出现频率较高的还是在C代码中.typedef与#define有些相似,但更多的是不同,特别是在一些复杂的用法上,就完全不同了,看了网上一些 ...

  8. Typedef 用法总结

    http://www.cnblogs.com/csyisong/archive/2009/01/09/1372363.html 不管实在C还是C++代码中,typedef这个词都不少见,当然出现频率较 ...

  9. C语言中typedf函数的用法,C语言中typedef用法详解

    在C语言中,经常有如下的用法: typedef struct  tag{    ...} MyType, *MyPtr; 一旦通过如上定以后,就可以用MyType来定义struct tag结构了. 以 ...

  10. c语言typedef的用法,C语言中typedef用法总结,看完就能像编程老手一样熟练运用...

    请看下文 C语言中typedef关键字应用比较常见,许多C语言初学者对它的用法不甚了解.事实上,我们可以用typedef来定义自己习惯使用的数据类型名称,可以替代自己所熟悉的基本类型.数组类型.指针类 ...

最新文章

  1. [JS]请填充代码,使mySort()能使传入的参数按照从小到大的顺序显示出来。
  2. 【No.5 类型转换导致的错误】
  3. unity3d鼠标拖拽模型,旋转模型
  4. SQL Server 2005数据库日志文件损坏的情况下如何恢复数据库
  5. 腾讯的迷你门户首页新闻用到的Silverlight技术引用
  6. Java使用自定义包
  7. 尴尬了!“中国版ins”绿洲 logo涉嫌抄袭,确认已下架
  8. dsoframer java_word在线编辑--------dsoframer.ocx 的使用(java 代码)
  9. 【098】在线Cron表达式生成器-在线生成Cron,格式化Xml
  10. 麒麟软件、麒麟操作系统、银河麒麟、中标麒麟、优麒麟、国产操作系统下载。
  11. linux rm 中文文件夹,在Linux下删除文件及文件夹(rm)
  12. java实现令牌桶算法
  13. iis启动服务时提示在本地计算机 无法启动iis admin服务,iis 依存服务和组没法启动...
  14. 阿里云虚拟主机、企业邮箱免费申请
  15. 如何禁用笔记本触摸板
  16. 获得root权限的命令 su和sudo命令
  17. VLC媒体播放器Web插件详细说明
  18. 补色的视觉原理(转)
  19. 直击进博会 | 丹佛斯、法孚、诺华、诺和诺德、波士顿科学、欧加隆、冯氏集团、阿迪达斯等在华签约合作...
  20. 用osworkflow写一个请假例子

热门文章

  1. Windows server用好windows server backup,发挥个人电脑该有的系统还原功能
  2. html标签思维导图
  3. OAuth2.0 工作流程
  4. 再谈访问修饰符——读《你必须知道的.net》
  5. 成长轨迹59 【ACM算法之路 百炼poj.grids.cn】【递归】【2694:逆波兰表达式】
  6. 常见虚拟主机目录对照及星外提权目录
  7. 编写多线程Java应用程序常见问题
  8. C语言-变量生存期及作用域
  9. 【C 语言】C 项目开发代码规范 ( 形参合法性判断 | 函数返回值局部变量 | 函数中不用全局变量 | 函数中使用局部变量接收形参 | 函数返回值 | 形参作返回值 | 形参返回值处理 )
  10. 【错误记录】Android 模拟器安装应用报错 ( INSTALL_FAILED_INSUFFICIENT_STORAGE )