非c语言有没有指针,使用C语言中的“不透明”指针,可以隐藏很多不想公开的细节...

虽说指针是C语言中比较复杂的语法,但是确实非常好用,因此我写过不少文章讨论C语言中的指针,相信对初学者理解指针有一定的帮助。

事实上,的确有读者私信我说看了这些文章,“总算不再畏惧指针了”。不过他同时也问了一个问题:C语言有“不透明指针(opaque pointer)”吗?要是有的话,什么样的指针才是不透明指针呢,有什么用呢?

eda806a3d3cd1e546a4cbbdd3a32f7a7.pngC语言的“不透明指针”有什么用?

C语言的“不透明指针”

坦诚地说,我比较讨厌向初学者说一些非常“专业”的名词,这不利于理解概念的本质,也容易让一些初学者产生畏惧的心理。“不透明指针”就是其中之一,其实它并不是多难的概念,甚至都不是什么新概念,只是一些基本知识的用法而已,只不过取了个非常装x的名字。

从字面意思来看,“不透明”意味着看不到内部,因此“不透明指针”即看不到内部定义的指针。这样说有些抽象,我们来看个例子:

typedef struct pmpi_s *pmpi;

上面这行C语言代码使用 typedef 关键字定义了一个结构体指针类型 pmpi,结构体由 pmpi_s 指定。虽然还没有具体定义结构体 pmpi_s,但是已经可以使用 pmpi 定义变量了,例如下面这行C语言代码:

pmpi p = NULL;

这里的指针 p 就是一个“不透明指针”,因为我们暂时看不到它到底指向什么样的内容,就像一个“不透明”的盒子一样。

52c166657df6a2d1782a315ceb56d821.png就像一个“不透明”的盒子一样

到这里,相信读者已经明白什么是C语言中的“不透明指针”了,而且也能看出,所谓的“不透明指针”其实并不是什么新概念,它不过是为了便于描述特定类型指针,方便同行之间交流取的名字而已。

C语言的“不透明指针”有什么用呢?

一般来说,稍大的C语言项目都不是一个人开发的,在多人协作开发中,少不了要调用别人编写的库函数,或者要把自己编写的库函数提供给别人使用。

即使是初学者也应该明白,要调用C语言函数,首先需要知道它的原型,因此通常情况下,库一般都会提供头文件,头文件里包含库里实现的函数原型或者数据结构的定义。例如我们常用的 就是标准 io 库的头文件,里面包含标准库函数(例如 printf)的原型。

可是,有时我并不希望将我编写的库所有细节公开给外界调用者。例如在源代码中,有这样的定义,相关C语言代码如下,请看:

472a7a2f36c79f296c7b5e3a92c2696e.png相关C语言代码

我只想在我自己的源文件(.c 文件)里使用结构体 pmpi_s,而不希望外界调用者知道它的结构,从而轻易地修改相关数据。通常情况下,只要不把这个定义写在对外公开的头文件里就可以了。但是,如果 handle_s() 也是需要公开的库函数其中一个,那么我将不得不提供 pmpi 结构体的定义,这样看来,似乎不能两全了?

当然不是,此时C语言的“不透明指针”就派上用场了,在头文件里放入结构体 pmpi 的不透明指针:

// fun.h 文件

typedef struct pmpi_s *pmpi;

void handle_s(pmpi p);

这样一来,如果我的同事需要调用我编写库函数时,只需要包含 "fun.h" 就可以了,他能够使用 handle_s() 函数,但是他不知道 pmpi_s 的具体结构,因为这是我想隐藏的内容。

小结

C语言的语法其实很精简,一些看似复杂的概念(例如“不透明指针”)其实只是对基本概念的引用而已,透明指针可以隐藏库的一些细节,一是为了安全,二是为了便于以后扩展——无论我在我的库内如何修改 pmpi_s 结构体,也不会影响到外界的调用者。

其实就本文的例子,我们完全可以使用“万能指针(void * 指针)”隐藏相关细节,这一点我之前的文章讨论过,不再赘述了。

8e1ab8214a95cf7eac928f3edad55dff.png点个关注吧

欢迎在评论区一起讨论,质疑。文章都是手打原创,每天最浅显的介绍C语言、linux等嵌入式开发,喜欢我的文章就关注一波吧,可以看到最新更新和之前的文章哦。

未经许可,禁止转载。

举报/反馈

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值