IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 【C/C++】如何理解void*与int之间的类型转换--以phtread_create为例 -> 正文阅读

[C++知识库]【C/C++】如何理解void*与int之间的类型转换--以phtread_create为例

要理解void*int之间地转换

首先理解intint*之间的转换

一般我们将int*理解为存放着某个地址的指针,地址所指的内容是一个int类型的值。

如果我们将int*存放的内容通过*取出来,输出到屏幕上如下所示:

int main(){
        int t = 10;
        int *p = &t;
        printf("%d\n",*p);
        return 0;
}

在这里插入图片描述
而实际上,int*存的就是个地址而已,我们可以将地址打印出来:

int main(){
        int t = 10;
        int *p = &t;
        long long tt =int)p;  // 这里强行将int* 转为了int,(C中不要求显示,C++要求显示转换)
        printf("%x\n%x\n",tt,&t);
        return 0;
}

在这里插入图片描述

可以看到虽然编译时报warning了,但是int*存放的地址打印出来了:50a0c86c

这个warning表示强制转换时类型的大小不同
在32位系统里,所有指针都是4个字节;64位系统里,所有指针都是8个字节。
而这里int*是8个字节的,转为long long也为8个字节所以不会丢失数据。
故可以忽略warning

上面已经实现了将int*类型转为了long long int类型,也就是将地址以数据的形式存到了long long int中。

VICE VERSA.

int类型转为int*类型,就是将int的数据存到了原本int*存放地址的位置。

int main(){
        int t = 10;
        int *p = t;
        printf("%lld\n",p);
        return 0;
}

在这里插入图片描述
这里我们将int型的数据转为了int*型,原本存放地址的指针直接存放了int型的值,在读出来的时候可以直接输出p而不需要*p,如果用了*p反而变成了去读10这个地址的内容,造成段错误。

这里同样报了warning,报的是没有显示进行转换,如果加上显示进行转换,会报类型大小不匹配也就是上面的错误,但是因为int*占8个字节,int占4个字节,所以不会丢失数据,故这里的warning也忽略。

intint*之间的转换延申到void*

void* 可以理解为无类型指针,既然是无类型指针,不禁让人联想到泛型这个概念。

当确定了要使用intvoid*转换,在实际使用中就将void*看作int*,保证类型大小不会丢失数据即可。

之所以我将它和泛型联系在一起,是因为void*出现在各种库函数和系统调用函数的接口参数中,而真正在使用这些函数的时候,我们传递的参数又是各种类型的,总是被显示或隐式地转换为void*

比如:

void * memcpy(void *dest, const void *src, size_t len);
void * memset ( void * buffer, int c, size_t num );

我们在使用的时候实际上进行了很多关于void*的隐式转换,void*在这些接口中更像是一个约束和规范,用来告诉我们这里可以传任意类型的指针。像上面这两个函数,我们就需要传指针或者数组就行了,因为这两个函数对指针参数的使用很明确。

应用场景

如果对指针参数的使用是 由我们自定义 的,那么传递void*就更单纯地只是一个约束,我们不一定非得传数组或者指针类型的数据,可以像上面那样传递int值强转为void*。

比如:

int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);

这个是创建线程的函数,第三个参数是一个回调函数,第四个参数是回调函数的参数。

这里就属于对指针参数的使用是我们自定义的,那么就意味着我们传递void*参数的时候不一定要传数组或者指针,可以像上面例子那样往地址中存放int值传递过去,在我们自定义的回调函数里面直接从指针里取值即可,比如:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>

void * tfn(void * arg){
        printf("%d\n",arg);
        return NULL;
}

int main(int argc, char * argv[]){
        pthread_t tid;
        int i=10;
        int ret = pthread_create(&tid,NULL,tfn,(void*)i);
        if(ret !=0) perror("pthread_create error");
        pthread_exit(NULL);
}

在这里插入图片描述
这是我遇到的int转void*的使用场景,且这样强转主要是要注意int和指针类型的大小会不会丢失数据。

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-11-15 15:39:53  更:2021-11-15 15:41:42 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 6:19:16-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码