理解指针址传递的一种思维方式——虚无指针

前言

这种方式是我在研究多线程编程的过程中发现的一种理解方式,虽然并不官方,但是便于理解指针的传递过程。

请看一看下面代码:

void *function(void* arg){
    int *return_data = (int*)arg;
    (*return_data)+=10;
    return (void*)return_data;
}

int main(){
    int a=10;
    pthread_t t1;
    pthread_create(&t1,NULL,function,(void*)&a);
    int *result;
    pthread_join(t1,(void**)&result);
    printf("%d\n",*result);
}

不过本次讨论的并非是线程的创建,而是pthread_join(t1,(void**)&result);这一行代码。

pthread_join

这个函数的函数原型是:int pthread_join(pthread_t __th, void **__thread_return),第二个参数是二级指针,使用二级指针的意义是为了在这个函数中能修改外部的值。

假设这个函数不使用二级指针,那么外部传入的值则在函数内部是副本,副本的修改不会影响到外界的值。

虚无指针理论

首先要明确一点,一个变量存在两个意义,一个是它的值,另一个是它的地址。

int *a = &b;

这样一个表达式,可以知道&b的意思其实就是一个a指针指向了b,那么以此为基础,来看一看(void**)&result这个表达式。

由前面的int *result可知,这个result变量是一个一级指针,那么&result就有点匪夷所思,如果加上(void**)就更加一团雾水,那么如果在此时引入“虚无指针”的概念,则会彻底解开谜团。

先说一说我对虚无指针的定义——一个没有实体,只存在逻辑的指针。所以这个指针只能存在于脑海中,因为它在现实中是不存在的。

理论结束,实践开始。

int** = &result,根据result是一级指针这一点,可以反推出它的虚无指针是二级指针,那么这个(void**)的强转也就变得清晰了,他实际上就是将虚无指针int**强转成了void**类型,然后传入函数phread_join

下面给出一个pthread_join的大致模型:

int pthread_join(pthread_t __th, void **__thread_return){
    //....
    *__thread_return = return_data;
   //....
}

当传入的指针被解引用之后,就成为了一级指针(也就是result),这个一级指针能被线程函数的返回值赋值了,比如这里被赋值为return_data的地址。

然后函数结束,此时的result的虚无指针渡过了(void**)&的影响范围,这里就引入虚无指针的第二特点——虚无指针的作用周期只存在于当前正在使用的函数,作用域结束则会坍塌

承接上文,虚无指针void**坍塌消失,result重新成为普通的int*,它的值存储的是return_data中存储的地址,所以printf("%d\n",*result);将地址解引用,得到return_data中的地址所指向的值。

版权声明:本站文章均为 原创内容 ,且遵循 CC BY-NC-ND 4.0 许可协议 ,转载请标明本文作者: 红笺画文 ,并注明转载出处
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇