C语言指针强制类型转换

【数据存储】指针强制转换 void指针又名万能指针,在现在的很多程序中,当参数不确定时就用万能指针代替,这一类的指针在线程\进程函数里特别常见。ANSIC规定,void指针可以复制给其他任意类型的指针,其他任意类型的指针也可以复制给void指针,指针是一个存储数据地址空间的变量,指针在工作时可以根据指针类型确定数据的字节大小,根据指针变量中存储的地址空间提取数据。p1存储的地址为a的低地址空间,char类型占1个字节,所以只读取1025的低四位。指针类型的p1可以直接打印指针指向的值,而void。... 阅读详情

概要:

C语言中,任何一个变量都必须占有一个地址,而这个地址空间内的0-1代码就是这个变量的值。不同的数据类型占有的空间大小不一,但是他们都必须有个地址,而这个地址就是硬件访问的依据,而名字只是提供给程序员的一种记住这个地址的方便一点的方法。但是,不同的变量在机器中都是0-1代码,所以,我们不能简单的通过检查一个值的位来判断它的类型。

例如,定义如下:

int a;

 float b;

double c;

 long double d;

(假设它们所占的字节分别是4、8、8、10,而且连续存储于某个地址空间,起始地址是100,则我们可以得到如下内存分布)

a变量就是由以地址100开始到103结束的4个字节内存空间内的0-1代码组成。b变量则是由以地址104开始到112结束的8个字节内存空间内的0-1代码组成。而在机器中,这些内存都是连续的0-1代码,机器并不知道100~103是整型而104~111是float型,所有这些类型都是编译器告知的。当我们用a时,由于前面把a定义为int型,则编译器知道从a的地址开始向后取4个字节再把它解释成int型。那么(float)a,就是先按照int类型取出该数值,再将该数值按照int to float的规则转换成float型。所以强制类型转换就是按照某个变量的类型取出该变量的值,再按照***to***的规则进行强制转转换。如果是(类型名)常数,则是将该常数按照常数to类型 的规则进行强制转换。

指针也是一个变量,它自己占据一个4个字节的地址空间(由于程序的寻址空间是2^32次方,即4GB,所以用4个字节表示指针就已经能指向任何程序能够寻址到的空间了,所以指针的大小为4字节),他的值是另一个东西的地址,这个东西可以是普通变量,结构体,还可以是个函数等等。由于,指针的大小是4字节,所以,我们可以将指针强制转换成int型或者其他类型。同样,我们也可以将任何一个常数转换成int型再赋值给指针。所有的指针所占的空间大小都是4字节,他们只是声明的类型不同,他们的值都是地址指向某个东西,他们对于机器来说没有本质差别,他们之间可以进行强制类型转换。
指针 to 指针的强制类型转换是指将指针所指的内容的类型由原先的类型转换为后面的类型。

int a = 1;

int *p = &a;

float *p1 = (float*)p;

则p和p1的值都是&a,但是*p是将&a地址中的值按照int型变量进行解释,而*p1则是将&a地址中的值按照float型变量进行解释。


鉴于指针之间这种灵活的强制类型转换的需求和出于简化代码的考虑,ANSI C引入了空指针即void*。void指针又名万能指针,在现在的很多程序中,当参数不确定时就用万能指针代替,这一类的指针在线程\进程函数里特别常见。

ANSI C规定,void指针可以复制给其他任意类型的指针,其他任意类型的指针也可以复制给void指针,他们之间复制不需要强制类型转换。当然任何地址也可以复制给void型指针。我们在《网络编程》中经常会看到accept(socket, (struct sockaddr *)&saddr_c, &lenth)之类的语句在&saddr_c之前需要增加代码(struct sockaddr *)是因为当此函数被设计的时候ANSI C还没有提出void*的概念。所有的地址统一用struct sockaddr类型标识,该函数的第二个参数也是指向struct sockaddr类型的指针,此处是强制类型转换。

当然,在某些编译器中不同类型的指针也可以进行直接赋值,但一般情况下会给出类型不匹配的警告。要求程序员显示的给出指针强制类型转换可以提醒程序员小心使用指针,对于明确程序目的具有一定的好处。

1、指针类型强制转换:

int m;

int *pm = &m;

char *cp = (char *)&m;

pm指向一个整型,cp指向整型数的第一个字节


2、结构体之间的强制转换

struct str1 a;

struct str2 b;

a=(struct str1) b;                  //this is wrong

a=*((struct str1*)&b);         //this is correct


3、关于一个程序的解释


int main(void)

{

    int a[4] = {1, 2, 3, 4};

    int *ptr1=(int *)(&a+1);

    int *ptr2=(int *)((int)a+1);

    int *c = *(a + 1);

    printf("%x, %x,%x\n", ptr1[-1], *ptr2,*c);

    return 0;

}

输出分别为4 和2000000,2

式子&a+1表示的是指针加法运算,而不是普通的数值加法运算

vs2008下,其中a = 0x001bfc18
(&a + 1) = 0x001bfc28
而 a+1 = 0x001bfc1c

 &a + 1 的值取决于a的类型如果a申明int a;
则&a + 1 = 0xFFFF5704  = a + 1
如果 int a(ArryLen);
则&a + 1 = 0xFFFF5700 + 4 * ArryLen <> a + 1

a 表示数组的起始地址,(int ) a 表示将a的地址转化为一个整形数,(int)a + 1 表示普通的数值加法运算,(int *)((int)a + 1)表示把(int )a + 1转化为整型指针的地址。该地址指向数组a(0)的第一个字节(从0计数),因为是int型的 所以需要四个字节的解释,所以结果是a(0)的后三个字节和a(1)的第一个字节组成的值,该值受大小端的影响。

 *(a + 1)  此时的a已经是一个常指针了,这个表达式计算出a所指向元素后面的第2个元素的地址,然后对它解引用得到相应的值。这个表达式等价于

int last = a[1]

将指针对象转化为整形传递并读取 DWORD ia =10;//定义了一个整形变量 LPVOID lp =(LPVOID) &ia;//取ia地址,然后转为指针 cout << lp << endl;//看看lp是什么 //cout << *lp << endl;//错误,不能直接从LPVOID指针类型中取值 //cout << (DWORD)(*lp)<< endl; cout << *(DWORD*)lp &... 阅读详情

相关推荐

[C语言中指针及强制类型转换]

在C语言中,指针是一种非常重要的数据类型,它允许我们直接操作内存地址,从而更加灵活地进行程序设计。此外,强制类型转换也是C语言中常见的操作方法,它可以将一个数据类型转换成另一个数据类型。指针和强制类型转换是C语言中非常常见的操作方法,它们可以帮助我们更好地理解程序设计和算法实现。需要注意的是,在使用指针和强制类型转换时,我们需要非常小心,避免出现不必要的错误。另一个常见的操作是强制类型转换,在C语言中,我们可以使用强制类型转换符号。然后,我们打印出这两个变量的值,并将双精度浮点型变量。

ByteKnight的博客 190

C++指针和指针类型强制转换

指针变量的本质:指针变量,本质上是一个变量,只是它是存放地址的变量,指针的类型代表的是它所指向的变量的类型。因此就有了指向整型、字符型、浮点型等其它类型的指针,但实际上所有类型的指针变量存放的都是int型(对于16位编译系统,int是2字节,对于32位编译系统,int是4字节)的地址。注意和指针指向对象的类型区分开),指针变量所存储的地址为指针所指向的对象的首地址。指针 to 指针的强制类型转换是指,将指针所指的内容的类型由原先的类型转换为后面的类型:即进行变量解释的时候,解释类型的转换。

js_hfut的博客 2631

STM32 USART高级功能全解析:IrDA、DMA、硬件流控与低功耗唤醒

USART是嵌入式系统中最基础的串行通信外设,其核心原理在于同步/异步时序控制与数据帧收发机制。现代MCU如STM32通过深度集成IrDA调制解调、DMA直传通道、RS232/RS485硬件流控及Stop模式唤醒等扩展能力,显著提升通信可靠性、吞吐效率与能效比。其中,IrDA SIR采用RZI编码实现抗干扰红外传输,DMA通过TXE/RXNE事件驱动实现零CPU干预的连续数据流,而硬件流控(RTS/CTS/DE)和低功耗唤醒(WUF+UESM)则分别保障工业现场鲁棒性与电池级超长待机。本文围绕STM32平台

weixin_28922227的博客 211

C---int和指针转换注意事项

这个标题也许写的有点不知所以然了,其实博主今天要讨论的自己在复习c/c++指针和引用的时候遇到的一些问题,慢慢说来….. 开始的时候写了这么一段代码: int a = 1; int* p = &a; printf("指针变量p的值 p - 16表示 是 = %p \n",p); printf("a的地址 p - 16表示 是 = %p \n",&a); /*输出 指针变量p

tingyun_say的博客 2万+

Zynq UltraScale+ MPSoC-AMP(linux+裸机)

接着 Zynq UltraScale+ MPSoC-双核裸机AMP继续 平台工具:zcu106,vitis2020.2,petalinux2019.2 文章目录1.cpu1跑裸机2.cpu0跑linux2.1petalinux设置2.2 app3.生成BOOT.bin4.zcu106测试 1.cpu1跑裸机 参照Zynq UltraScale+ MPSoC-双核裸机AMP建立的工程进行修改。BSP中stdin与out修改为uart1,uart1给裸机用,uart0给linux用。 ddr空间裸机与linu

zhuxl24的博客 5195

使用Power Apps实现SharePoint Online列表的下拉菜单的级联选择

在SharePoint列表中添加数据的时候,下拉菜单的级联选择一直是一个非常实用的功能,尤其是有很多数据的情况,级联选择可以根据上一层的选择,自动过滤下一层的选择,方便用户查找和选择准确的信息。一个最常用的情景是选择供应商的地区和国家,例如有三个列表,一个是供应商所在的大洲,一个是国家,一个是供应商。当用户选择州的时候,会自动列出属于这个州的国家。避免用户迷失在大量的数据中。 这里展示一下如何在...

shrenk的专栏 7808

c语言指针强制类型转换

概要: C语言中,任何一个变量都必须占有一个地址,而这个地址空间内的0-1代码就是这个变量的值。不同的数据类型占有的空间大小不一,但是他们都必须有个地址,而这个地址就是硬件访问的依据,而名字只是提供给程序员的一种记住这个地址的方便一点的方法。但是,不同的变量在机器中都是0-1代码,所以,我们不能简单的通过检查一个值的位来判断它的类型。 例如,定义如下: int a; float b; double c; long double d; (假设它们所占的字节分别是4、8、8、10,而且连续存储于某个

赵凯月的博客 9496

Ubuntu 20.04 LTS下5分钟搞定ONLYOFFICE协作空间社区版(Docker版保姆级教程)

本文提供了一份在Ubuntu 20.04 LTS系统上,通过Docker快速部署ONLYOFFICE协作空间社区版的保姆级教程。内容涵盖从系统准备、Docker环境搭建,到执行自动化安装脚本、完成Web初始化的全流程,并详细说明了部署后的安全配置、数据备份及基本运维要点,帮助用户高效构建私有、安全、可控的团队文档协作平台。

weixin_28826961的博客 260

c语言指针强制类型转换的应用

指针的强制类型转换可以灵活的对单个和多个字节的数据结构进行操作

j5856004的博客 1万+

unity制作交互视频/互动视频

unity制作交互视频/互动视频 思路 1.先让unity播放视频 2. 视频播放结束后,视频暂停,按钮出现 3.按钮跳转下一个视频 视频播放 先创建UI-Raw Iamge 在Raw Iamge 挂载组件 Video Player 接着挂载视频播放的脚本 using UnityEngine; using UnityEngine.UI; using UnityEngine.Video; publi...

weixin_45588911的博客 8423

LDPC码介绍:基础&编码&译码

本博客介绍了LDPC码的基本原理,其中包括校验矩阵的构造、Tanner 图和编译码的基础知识。

渺小的颗星的博客 4308

C语言类型转换-自动类型转换、强制类型转换、指针类型转换

点,真正体系化!**

2401_84247449的博客 1493

使用 Prometheus 监控 Spring Boot 应用

本文介绍了使用SpringBoot+Prometheus+Grafana实现应用监控的方案。首先在SpringBoot项目中集成Micrometer和Actuator组件,通过配置暴露Prometheus监控端点。接着配置Prometheus采集应用指标数据,并通过Grafana可视化展示。具体步骤包括:1)SpringBoot集成Micrometer;2)配置Prometheus抓取应用指标;3)安装Grafana并导入SpringBoot监控模板;4)展示JVM和业务指标。该方案可以实现对SpringB

蔡定努 430

C语言: 指针强制类型转换

1. 指向字符串的指针强制转换成指向整型的指针: #include #include #include int main(int argc, char** argv) {  char buffer[500];  memset(buffer, 0, 500);   *(int *)buffer = 123;   printf("buffer is %d\n", *buffer

May.Ouyang的专栏 4228

26. Fabric2.2 司法存证的智能合约分析

有很多同学反馈 Fabric 智能合约读起来比较费劲,对于新手不友好看不懂,这里选择一个司法存证的智能合约,阅读、分析智能合约基础框架与核心流程代码,培养大家智能合约编写的方法论。

菜鸟的博客 1338

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

c语言指针的强制类型转换,c语言指针的强制转换

在c语言中经常看到以下类似的代码:int x = 1;(char*)&x;这样的形式的代码,这个里面就涉及一个类型转换的问题。以下是在VC6.0中调试的结果代码:int main(int argc, char* agrv[]){int num = 1;printf("&num=%p \n", &num);printf("&num+1=%p \n", &num...

weixin_42514627的博客 5013

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

C陷阱与缺陷读书笔记(一) —C语言函数指针的强制类型转换

首先回顾一下函数指针,函数指针是指向函数的指针,不同于函数返回的指针类型数据,比如int* (*p)(); 这句话就是声明一个函数指针p,他指向一个"返回值类型为指向整型数据的指针类型的函数"。也就是声明普通的指针类型变量我们是写上类型名后面接*,而声名函数指针类型我们是写函数的返回值类型后面括号里面写*接函数指针变量名,再接()象征形参列表,如果是需要传参的函数,还要在里面写上参数类型,然后后面写不写形参都可以,类型声明而已,能不写就不写吧。或者这样想:"声明普通指针类型是把*放在后面,而声明函数指...

qq1003735377的博客 2132

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

上一篇: 复制构造函数(拷贝构造函数)
下一篇: Android Alarm自上而下 调试浅析
计算机与认知
博客等级 码龄14年 31粉丝 19原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值