有种很方便的写法。

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

再谈typedef(重点为函数指针)相关推荐

  1. typedef定义的函数指针

    再谈 typedef(重点为函数指针) 有种很方便的写法. typedef int *p: p pointer: 这时直接把pointer带入原式中,取代p然后去掉typedef,得到的结果就是int ...

  2. 【C/C 】浅谈C/C 中函数指针与回调函数

    01.函数指针 1.1.函数指针定义 一个函数总是占用一段连续的内存区域,函数名在表达式中有时也会被转换为该函数所在内存区域的首地址,这和数组名非常类似.我们可以把函数的这个首地址(或称入口地址)赋予 ...

  3. 再谈正态分布或高斯函数

    它的历史不知道,如何推导出来的,没管啊,不过我很有兴趣看看啊,但没有看.高斯函数的用处太多了: 首先说明一点哦:正态分布是高斯函数的积分为1的情况: 一维情况下: 一维高斯高斯函数的公式: 而正态分布 ...

  4. typedef 返回类型(*Function)(参数表) ——typedef函数指针

    //首先看一下函数指针怎么用 #include <iostream> using namespace std; //定义一个函数指针pFUN,它指向一个返回类型为char,有一个整型的参数 ...

  5. 结合typedef更为直观的应用函数指针

    "函数指针"的本质是一个指针变量,只不过该指针变量指向函数. 1:简单应用 形式1:返回类型(*函数名)(参数表) [html] view plaincopy #include & ...

  6. typedef和函数指针定义

    2019独角兽企业重金招聘Python工程师标准>>> 用typedef为一个函数指针类型起别名 typedef int (*p1)(int,int); 定义一个函数指针 int ( ...

  7. typedef函数指针

    由于之前学习C++这块内容并没有经过太多实践,这块内容已经忘记了不少,现在学到动态库用到这块内容,又重新整理了.接下来的几天将会学习更多的动态库静态库的知识,学完之快内容之后,就学习excel等off ...

  8. 函数指针,指针函数,函数指针数组

    这是一个群友发的笔试题目,里面涉及的东西也比较有意思. 直接看代码 void (*f[])(char *) 这个是个什么东西? 我们先看看下面的东西 函数指针和指针函数的定义 我们看个代码 int * ...

  9. C 基础——指针函数与函数指针

    一.指针函数的定义 指针函数,顾名思义,返回指针的函数.其一般定义形式如下: 类型名 *函数名(函数参数列表): 其中,后缀运算符括号()表示这是一个函数,其前缀运算符星号*表示此函数为指针型函数,其 ...

最新文章

  1. ad 原理图差分线_usb hub原理图及pcb设计
  2. STL中各容器和适配器类的定义
  3. scrapy-splash抓取动态数据例子三
  4. PyQt5 笔记5 -- 消息框(QMessageBox)
  5. python可以这样学读书笔记_Python小白的读书笔记
  6. Android 8.0学习(25)---系统的应用图标适配
  7. 量子计算机西南交大,交大量子光电实验室
  8. 合成谬误与公地悲剧(为何设置产品总监职位及核算名义成本)
  9. [undo]ip address ppp-negotiate
  10. cs229线性回归和逻辑回归总结
  11. 安信可推荐 | 安信可ESP-C3模组和ESP32-S3模组的软件和硬件对比区别
  12. RuntimeError: Exporting the operator affine_grid_generator to ONNX opset version 9 is not supported.
  13. QT 使用 qcustomplot 编译出错
  14. 百宝云COM组件操作教程
  15. android 9.0 10.0 上报鼠标左键右键给app调用
  16. POS标记——HMM模型
  17. Python Web简介
  18. 中国保险中介行业市场规模调研及投资可行性研究报告2022-2027年
  19. html手指动图,推荐10款gif动态图片特效(收藏)
  20. 2022年520最实用的礼物,苹果平板的触控笔

热门文章

  1. 投影html连接电脑,电脑怎么连接投影仪?投影仪的详细安装使用教程
  2. 计算机桌面图标有箭头,电脑桌面图标为什么会有一个小箭头,原来没的呀,
  3. [人工智能]手语识别转文字落地深圳医院,厉害了我的腾讯
  4. MongoDB 3.0+访问数据库的方法
  5. 计算机辅助外文文献,计算机辅助设计建筑CAD论文中英文对照资料外文翻译文献.doc...
  6. 手机辐射到底有多厉害!65分钟将生鸡蛋煮熟
  7. 科学解释成功者成功的秘诀
  8. 格力电器成为银隆新能源股东 持股30.47%
  9. 京东集团副总裁王楠:数智化是打造国际消费中心城市的必由之路
  10. 赔了24亿,干到中国第一!最“不要命”航班,竟让无数人抢着坐?