OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 5845|回复: 8

C语言指针强制类型转换的一点疑问,希望大家不吝赐教!

[复制链接]

7

主题

34

帖子

0

精华

初级会员

Rank: 2

积分
126
金钱
126
注册时间
2015-9-13
在线时间
9 小时
发表于 2015-12-6 20:56:45 | 显示全部楼层 |阅读模式
5金钱
[mw_shl_code=c,true]#include <stdio.h> int main(void) { char *pc; int * pi;[/mw_shl_code] [mw_shl_code=c,true] int i=256;[/mw_shl_code] [mw_shl_code=c,true] char c=255;[/mw_shl_code] [mw_shl_code=c,true] pc=&c;[/mw_shl_code] [mw_shl_code=c,true] pi=&i; pc=(char *)pi; //疑问处 }[/mw_shl_code]
既然所有指针类型都是占四个字节,那么将int类型指针赋给char类型指针是不会导致数据丢失的吧。既然这样按我的理解,
将右值指针赋给左值指针(两种指针类型不同)只是程序员希望将右值指针所指向的数据类型通过指针按照左值指针指向的数据类型来访问。
既然要通过左值指针来访问右值指针所指向的数据类型,那么,问题来了,指针在定义的时候,就已经知道自己在加加或者减减操作时应该访问多少字节的内存,
或者加减n时应该跳过多少字节的内存。既然要用左值指针来进行后续的数据访问,那么为什么不直接把右值指针的地址给左值指针,(正如我第一句所说的,都是四字节不会丢失数据)
而要进行强制类型转换呢?
而且疑问处的代码去掉(char *),在VC++6.0   还有多版的c在线编译器上均不会报错…是因为像我理解的一样所以才不会报错,还是其他。还是必须要进行强制类型转换?希望大家指点一下迷津!

最佳答案

查看完整内容[请看2#楼]

pc=(char *)pi;左右都是指针,对于某些编译器,确实只是复制了一个地址,无需关心这个地址的类型,反正在后面使用pc的之后,会按照pc的类型来访问。因为这里没有涉及到指针的运算,编译器在这里能比较了解程序员的意图,所以不加强制类型转换编译的时候也不会导致歧义,只是不太严谨而已。这个应该和编译器设置有关,我用的iar环境要求必须强制转换,否认编译报错。 对有的场景强制转换则对于表达程序员意图就是必须的。 ...
0 error 0 warning
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

9

主题

538

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3371
金钱
3371
注册时间
2015-1-7
在线时间
794 小时
发表于 2015-12-6 20:56:46 | 显示全部楼层
pc=(char *)pi;左右都是指针,对于某些编译器,确实只是复制了一个地址,无需关心这个地址的类型,反正在后面使用pc的之后,会按照pc的类型来访问。因为这里没有涉及到指针的运算,编译器在这里能比较了解程序员的意图,所以不加强制类型转换编译的时候也不会导致歧义,只是不太严谨而已。这个应该和编译器设置有关,我用的iar环境要求必须强制转换,否认编译报错。

对有的场景强制转换则对于表达程序员意图就是必须的。
unsigned char j = 0;
j = *((char *)(pi)+1);
这里加和不加(char *)都是合法,但是不同的两种编译结果

个人理解
机器生汇编,汇编生B,B生C,C生万物.... 经过长期对C语言的研究,目前只有两个方面不懂:这也不懂,那也不懂
https://github.com/ianhom
回复

使用道具 举报

7

主题

34

帖子

0

精华

初级会员

Rank: 2

积分
126
金钱
126
注册时间
2015-9-13
在线时间
9 小时
 楼主| 发表于 2015-12-6 21:08:14 | 显示全部楼层
自己顶一下~
0 error 0 warning
回复

使用道具 举报

7

主题

34

帖子

0

精华

初级会员

Rank: 2

积分
126
金钱
126
注册时间
2015-9-13
在线时间
9 小时
 楼主| 发表于 2015-12-6 21:14:01 | 显示全部楼层
在线等答案,要不会睡不着的…
0 error 0 warning
回复

使用道具 举报

7

主题

34

帖子

0

精华

初级会员

Rank: 2

积分
126
金钱
126
注册时间
2015-9-13
在线时间
9 小时
 楼主| 发表于 2015-12-6 21:26:46 | 显示全部楼层
我问的问题太弱智了吗?怎么没人理我?
0 error 0 warning
回复

使用道具 举报

7

主题

34

帖子

0

精华

初级会员

Rank: 2

积分
126
金钱
126
注册时间
2015-9-13
在线时间
9 小时
 楼主| 发表于 2015-12-7 18:37:37 | 显示全部楼层
回复【5楼】ianhom:
---------------------------------
多谢大神指点
0 error 0 warning
回复

使用道具 举报

60

主题

409

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2814
金钱
2814
注册时间
2012-10-17
在线时间
653 小时
发表于 2016-1-5 17:09:31 | 显示全部楼层
單純不讓編譯器報錯而已...

-----------------------------------------------------------------------------------------------------
既然所有指针类型都是占四个字节,那么将int类型指针赋给char类型指针是不会导致数据丢失的吧。

這句話怪怪的...指針是4個字節只是因為它取址空間能到32bit 跟你數據丟不丟一點關係都沒有....
回复

使用道具 举报

10

主题

560

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1739
金钱
1739
注册时间
2014-6-27
在线时间
943 小时
发表于 2016-1-5 23:57:20 | 显示全部楼层
首先指针就是一块被分配的内存,指针的宽度就是你MCU的机器宽度,比如8位宽度,地址0~255,指针也是8位,它指向的范围就是0~255,以此类推,16位字宽的,指针占2个字节,它指向的范围是0~65535,你定义一个指针*p,比如MCU是16位字宽的,假设指针被分配地址100和101两个字节,它占2个字节,所以能指向0~65535的地址范围,无论什么类型的指针占内存大小都是一样的。


指针有了,指向什么类型的数据是另外一回事,指针操作数据,比如指针操作char类型数据,说明它指向的内存地址是以1个字节操作的,假如字符指针*p,占地址100和101,指向字符数组a[2],a的起始地址是65530,占地址100和101的指针指向数组a,说明p指向65530地址了,如果指向a[1],因为p是字符指针,字符占一个字节,p指向地址就进一个字节,指向63331了,如果p和数组a是整型,p指向a[1]就进2个字节了,指向65532了。

所以,指针类型决定了指针步进地址的大小,所以你可以把指针强制转换成任何类型,指针本身大小永远不变。
回复

使用道具 举报

3

主题

130

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
373
金钱
373
注册时间
2015-3-7
在线时间
43 小时
发表于 2016-1-6 08:02:02 | 显示全部楼层
楼上正解。“指针类型决定了指针步进地址的大小,所以你可以把指针强制转换成任何类型,指针本身大小永远不变。”
数据类型是char,就访问一个字节,是int类型的,就访问4个字节大小。指针本身就是4个字节。
为人莫作千年计,三十河东四十西,莫欺少年穷。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-23 12:47

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表