c语言-强制转换
#c语言,#强制转换
个人拙见【20220709】
第一次写博客,还不熟悉,所以我就简单粗暴的来吧。
//以下是用我自己的话描述的,所以某些概念可能不一样,但是思路是没问题的
对于C语言,强制转换大概有两种类型:1. 对数据有改变 2.对数据不改变
1. 对数据有改变:
很明显的,有
float a = 3.25; //二进制数值:11.01 printf("%d\n", (int)a);
//结果为:
//3
对于a,是float型变量, 内存的原数据,并不是,直接存放a的二进制数值11.01,而是经过一个固定算式的转换【这里就不展开说明】
(int)a 会先转换,得到a的数值3.25, 然后阉割小数部分【阉割过程由cpu解决,我们不用管】,只留下3【二进制11】
数据是会发生变化的【这里的数据,我猜的是在cpu计算时的数据】
2.对数据不改变:
float a = 3.25;
(int*)&a; //&a是float*型数据, 强转为int*数据。同样不改变原数据。
对于C语言,一切皆数据
int b = 122; //char是最小整数型变量,范围:[-128,127]
//只不过我们可以利用acsii码表来表示字符。122 == 'z'
(char)b; //这里,也不会改变原数据。
//由于大小端序的问题,也会带来一些下面问题:
'z' == 122; 122 == 0x7A;
'y' == 121; 121 == 0x79;
printf("%c\n",0x7900007A);
//x86平台,大端序原数据内存里为0x7A 00 00 79,所以%c,只读取最后一个字节,0x7A, 也就是'z';
printf("%c\n",0x7A000079);
//类似上面
printf("%c\n", (char)b);
//结果:
z
y
z
所以像这种转换(char)122,都不会改变数据。
别看着好像是 int 转 char 似乎类型变了,本质上类型并没有大变。
char 1字节整型
int 4字节整型
long 8字节整型
其实这一串,都同源同根,只不过长度不一样,能表示的范围不一样而已。
而char 只不过还用来表示字符量,但前提是,你得告诉电脑 (%c),【用该整形量表示字符】。
我们再来看,指针类型强转,这也不改变数据,只是改变类型
float a = 3.25; (int*)&a; //&a是float*型数据, 强转为int*数据。同样不改变原数据。
int c = *(int *)&a; //这里 直接使用内存的原数据
对于指针类型的强制转换,其实精髓还是【一切皆数据】
char c = 'z'; char *p = &a; //不改变数据,&a多少,p就多少
(unsigned long)p; //这个数值跟p本身数据,没什么区别。p多少,(unsigned long)p就多少
(unsigned int)p; //这个上面说过,大小端序问题,只能读到,最后4字节【本身p,8字节】
//以下数据都不改变,也不丢字节,只改变类型。
(int *)p;
(float *)p;
(long *)p;
//同时,也带来另一个影响:【影响内存的解释方式】
*(int *)p; //这里将以int的方式解释p所指内存的数据,
// 'z' 即122,即0x7A, 大端序【7A, 非法内存,非法,非法】
// 后面3字节,并没有申请,非法内存,因此会出bug
//其他几个类似
不过,通过* 访问,这已经是后面的事情了,
没必要把 这个强转,跟后面的*访问,绑一起,
本身是两个过程。强转,在访问前已经结束。
还是那句话:【一切皆数据】
从 char * 类型,转换成 int * 类型。数据没变,类型变了而已,都是数据
做一个总结:
强转有两种类型:
1. 改变原数据
int和float 之间强转
2.不改变原数据
类型改变方式:
1)丢字节,来改变类型。
如:char a = 0x7A 00 00 79; 丢三字节,只拿到0x79【大端序】
2)不丢字节,直接改变类型。
如:p是char* 数据,(int*)p; 仅改变类型
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了