博客
关于我
C指针之函数指针与typedef
阅读量:341 次
发布时间:2019-03-04

本文共 1791 字,大约阅读时间需要 5 分钟。

函数指针与typedef

函数指针的实质

函数指针实际上与普通指针在本质上没有太大区别。无论是函数指针、数组指针还是普通的指针,它们在内存中都占据4个字节(在32位系统中),这一点是值得注意的。然而,函数指针的特殊之处在于它指向的并非单一的数据值,而是一段代码。这段代码在编译时会被编译器转换成一系列机器指令,形成连续的代码块。

函数的实质是一个存储在内存中的代码段。当编译器处理函数时,它会将函数名转换为该段代码的起始地址。在C语言中,函数名就是用来表示这个地址的符号。因此,函数指针实际上是一个普通的指针变量,其类型定义为“函数指针类型”,而它的值则是某个函数的起始地址。

函数指针的书写与分析方法

C语言是强类型语言,这意味着每个变量都有特定的类型,编译器会严格检查类型是否匹配。在C语言中,虽然所有指针变量类型本质上都是一样的,但为了让编译器能够正确进行类型检查,编写函数指针时需要遵循特定的写法。

函数指针的写法通常会比普通指针更复杂,因为它需要提供更多的类型信息。例如:

  • int *p; 表示p是一个指向整数的普通指针。
  • int (*p1)[5]; 表示p1是一个指向整数数组的数组指针,其数组长度为5。
  • void (*pFunc)(void); 表示pFunc是一个指向返回值为void且接受void参数的函数的函数指针。

需要注意的是,函数名和数组名在做右值时有显著的区别。函数名可以直接使用或使用取地址运算符(&),而数组名使用取地址运算符时会改变其类型。例如:

  • func1&func1 在C语言中是等价的。
  • a&a 在数组上则是不同的,因为数组在编译时会被转换为指针类型。

复杂函数指针的示例

假设我们有一个函数 strcpy,其定义为:

char *strcpy(char *dest, const char *src);

对应的函数指针定义为:

char *(*pFunc)(char *dest, const char *src);

在使用时,可以通过以下方式调用:

char a[5] = {0};char *dest = a;char *src = "abc";pFunc(dest, src);printf("a = %s.\n", a);

需要注意的是,函数指针的使用需要确保其类型与函数匹配。例如,strcpy 函数的返回类型是 char *,所以函数指针的定义应与此匹配。

typedef的用法

typedef 是C语言中的一个关键字,用于定义或重命名类型。它允许我们将复杂的类型名称简化为更易于记忆的别名。

C语言中的类型分为两类:

  • 编译器定义的原生类型:包括 intdouble 等基础数据类型。
  • 用户自定义类型:包括数组类型、结构体类型、函数类型等。
  • typedef 的主要作用是为用户自定义类型提供简化名称。例如:

    typedef char* (*pType)(char *, const char *);

    这定义了一个名为 pType 的新类型,其表示一个指向 char* 的函数指针。

    需要注意的是,typedef 定义的是类型,而不是变量。它不会在内存中分配任何空间,而是仅仅为类型名称提供了新的表示方式。

    以下是 typedef 在函数指针中的应用示例:

    // 定义一个函数指针类型typedef char* (*pType)(char *, const char *);// 定义一个函数指针数组typedef char* (*pType[5])(char *, const char *);// 定义一个函数指针数组指针typedef char* (*(*pType)[5])(char *, const char *);// 使用pType p3;  // 等效于 char* (*p3)(char *, const char *)pType p4;  // 等效于 char* (*p4)(char *, const char *)

    通过 typedef,我们可以将复杂的类型名称简化,使代码更加易读和维护。

    总结

    函数指针和 typedef 是C语言中的核心概念。函数指针允许我们通过变量存储函数地址,调用函数的实现代码。typedef 则为我们提供了一个简化类型定义的方法,使得代码更加灵活和易于维护。

    转载地址:http://adur.baihongyu.com/

    你可能感兴趣的文章
    英特尔强势上新一大波数据产品,小伙伴们“奔走相告”…… | 极客头条
    查看>>
    成为最大的独立开源公司,对SUSE意味着什么? | 人物志
    查看>>
    红帽:将开源进行到底
    查看>>
    SaaS前世今生:老树开新花
    查看>>
    微信小程序生命周期 / 页面的生命周期 / 页面的用户行为
    查看>>
    用C语言散列表实现电话薄
    查看>>
    微信小程序云开发手机商城项目源码+数据库+云后台+部署 (毕业生福利!)
    查看>>
    Maven的配置
    查看>>
    如何在bilibili上下载学习视频?
    查看>>
    Python爬虫利器之Beautiful Soup的全世界最强用法 五百行文章!
    查看>>
    09-Vue之本地应用v-for指令
    查看>>
    03-selenium元素定位
    查看>>
    19-selenium操作已启动的浏览器
    查看>>
    11-Python-作用域和命名空间
    查看>>
    2020.2.13普及C组 罗密欧与朱丽叶的约会【纪中】【前缀和】
    查看>>
    纪中2020.3.4普及C组模拟赛总结
    查看>>
    纪中2020.3.18普及C组模拟赛总结
    查看>>
    YbtOJ 递推算法课堂过关 例5 平铺方案【递推(简单DP)】
    查看>>
    YbtOJ hash和hash表课堂过关 例1 字符串哈希【hash】
    查看>>
    YbtOJ hash和hash表课堂过关 例4 单词背诵【hash】【二分】
    查看>>