搜索
bottom↓
回复: 31

c语言 大伙帮忙看看这样写为什么不对? 指针的问题

[复制链接]

出0入0汤圆

发表于 2010-11-19 22:52:02 | 显示全部楼层 |阅读模式
unsigned short * pa;
unsigned char a;

pa = &a;
这样提示
Error[Pe513]: a value of type "unsigned char *" cannot be assigned to an entity of type "unsigned short *"

加上强制转换
(unsigned char *)pa = &a;
会提示
Error[Pe137]: expression must be a modifiable lvalue
想把a的地址强制付给pa 即用*pa访问a的值该如何操作?
如果写成
pa = (unsigned short*)&a;
可编译通过,但这样用*pa访问的就不是a的值了啊。

请支招,谢!

阿莫论坛20周年了!感谢大家的支持与爱护!!

曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……

出0入9汤圆

发表于 2010-11-19 22:58:30 | 显示全部楼层
一开始定义为unsigned char *pa就可以了

出0入0汤圆

发表于 2010-11-19 23:05:04 | 显示全部楼层
pa = (unsigned short*)&a; 写法是正确的。访问不正确,是因为你用一个short型访问一个unsigned char型。因为数据排列中,字节是最小单位。所以,会把a的后面的一个字节地址数据也包含进来。所以,不明白你的应用,为什么需要用,unsigned short* 去指向unsigned char型数据。

pa = (unsigned short*)&a;
可编译通过,但这样用*pa访问的就不是a的值了啊。

你这样的意义何在,不懂。

出0入0汤圆

发表于 2010-11-19 23:10:03 | 显示全部楼层
1L正解
unsigned char * pa;
unsigned char a;

此贴可以结了

出0入0汤圆

发表于 2010-11-19 23:13:34 | 显示全部楼层
不同类型的指针,并且short对应的长度不一定是char的长度哦

出0入0汤圆

 楼主| 发表于 2010-11-19 23:49:49 | 显示全部楼层
谢楼上各位
因为pa有时要访问short型(16bit),有时访问char型,所以定义成short型,现在的问题是如何用一个指针访问不同类型的数据?
难道就没有办法了?!

出0入0汤圆

 楼主| 发表于 2010-11-19 23:51:42 | 显示全部楼层
我现在的方法是
unsigned short * pa;
unsigned short a;
unsigned short b;

但是a是个0到99的数据。

期待更合适的办法。

出0入0汤圆

发表于 2010-11-20 02:44:17 | 显示全部楼层
unsigned short * pa;  
unsigned short a;  
unsigned short b;

既然已经将a定义为unsigned short了,你还管它是多少数干嘛呢,直接用这个unsigned short 的指针访问就没问题了。不知LZ写个unsigned short a是何意?是不是写错了,你是想写unsigned char a;?

如果有字符和整型的数据,可以将整型数据定义一个联合结构(将整型分为2个字符型),然后将指针定义为字符型,这样就可以同时操作你的整型和字符型数据了。

出0入18汤圆

发表于 2010-11-20 08:04:29 | 显示全部楼层
我来说说吧

指针本身是没什么数据类型的  因为指针本身存储的就是个地址  地址 的类型都是一样的

因此 在定义指针时的类型是指   该指针指向数据的类型,比如 要定义一个 int型的数 就要  int *pa;如果定义一个指向

unsigned char 类型的数  那么就要定义一个  unsigned char *pa;

出0入0汤圆

发表于 2010-11-20 08:22:20 | 显示全部楼层
还不如不用指针。

出0入0汤圆

发表于 2010-11-20 08:40:28 | 显示全部楼层
需要访问不同类型的指针,请定义成void* pa;
访问相应类型时做相应类型的强制转换
*(unsigned char*)pa
*(unsigned short*)pa

出0入0汤圆

发表于 2010-11-20 10:15:19 | 显示全部楼层
你访问的时候再强制转换一次指针类型不就得了.....

出0入0汤圆

发表于 2010-11-20 10:25:47 | 显示全部楼层
呵呵,你可以转换指针的类型。
unsigned short * pa;
unsigned char a;

//pa = &a; //这句改掉
(unsigned char *)pa=&a;//这样就可以了。指针本身的数据长度是不变的,只是指向的数据的类型和长度不同

出0入0汤圆

 楼主| 发表于 2010-11-20 10:35:37 | 显示全部楼层
谢楼上
我这样写
(unsigned short*)pa = &a;
(unsigned short*)pa = &b;
不能编译通过
Error[Pe137]: expression must be a modifiable lvalue   
我写成这样
(unsigned short*)pa = (unsigned short*)0x80000000;
也出现同样的错误  用的是IAR 5.2。

  
回复【7楼】powersky
-----------------------------------------------------------------------

回复【9楼】t2397362
-----------------------------------------------------------------------

回复【8楼】dengxiaofeng 天下的人
-----------------------------------------------------------------------
都定义成short是可以但是数据多的花就会浪费不少ram空间的。最好是能定义成unsigned char a,又能访问,现在是这样定义编译会出错。

我现在的想法是通过一个这真访问不同类型的数据,在访问数据前需将数据的地址付给该指针,但编译出错。

出0入0汤圆

 楼主| 发表于 2010-11-20 10:38:07 | 显示全部楼层
回复【9楼】t2397362
-----------------------------------------------------------------------

回复【12楼】shamork 氧化还原合成单片机
-----------------------------------------------------------------------

这样试过了 编译出错
Error[Pe137]: expression must be a modifiable lvalue  
这点楼主位有说明

出0入0汤圆

发表于 2010-11-20 10:38:23 | 显示全部楼层
你把完整的程序贴上来。要不然我就断章取义了。

出0入0汤圆

发表于 2010-11-20 10:39:18 | 显示全部楼层
#include <regx51.h>
unsigned short * pa,b=0x38; //数字8
unsigned char a='A';

void main(void)
{

    //pa = &a; //这句改掉
    (unsigned char *)pa=&a;//这样就可以了。指针本身的数据长度是不变的,只是指向的数据的类型和长度不同
}

我用的Keil 8.04

Build target 'Target 1'
assembling STARTUP.A51...
compiling aa.c...
linking...
Program Size: data=15.0 xdata=0 code=161
"aa" - 0 Error(s), 0 Warning(s).

出0入0汤圆

发表于 2010-11-20 10:44:36 | 显示全部楼层
你贴下完整的程序,就是只有个框子,还有你的句子,还有编译器的编译结果,图片文字都可以。
我的转化是没有问题的。注意:
unsigned short *pa,b;
unsigned char a;
unsigned int c;

用得时候:
(unsigned char*)pa   =&a;//pa转换成指向unsigned char类型数据的指针
(unsigned short *)pa =&b;//因为b是unsigned short ,所以指针要变成unsigned short *
(unsigned int *)pa   =&c;//c是unsigned int,所以pa要被强制转换成unsigned int *——指向unsigned int 型数据的指针
取值的时候:
当然你要重新转换成你想要得到的类型。因为pa里仅仅是个地址,你可以决定这个地址指向的数据的类型。
d=*((unsigned int *)pa);//d是unsigned int
d=*((unsigned short *)pa);//d是unsigned short
d=*((unsigned char *)pa);//d是 unsigned char

出0入0汤圆

发表于 2010-11-20 10:47:10 | 显示全部楼层
用共同体

或者,只定义一个
u16 pa
需要高位时用
*((u8 *)&pa)
低位
*((u8 *)&pa + 1)

或者10楼的办法

注:哪个是高位要试一下,我不知道你的芯片是高位在前还是在后

出0入0汤圆

 楼主| 发表于 2010-11-20 11:46:48 | 显示全部楼层
建了个小工程实验
//main.c

int main( void )
{
    void * pa;
    unsigned char a;
    unsigned short b;
   
    pa = &a;
    *(unsigned char *)pa = 10;
    pa = &b;
    *(unsigned short *)pa = 10000;

    return 0;
}
这样正常

出0入0汤圆

 楼主| 发表于 2010-11-20 11:47:08 | 显示全部楼层
int main( void )
{
    void * pa;
    unsigned char a;
    unsigned short b;

    (unsigned char *)pa = &a;
    *(unsigned char *)pa = 10;
    (unsigned short *)pa = &b;
    *(unsigned short *)pa = 10000;

    return 0;
}
这样出错

出0入0汤圆

 楼主| 发表于 2010-11-20 11:48:50 | 显示全部楼层
IAR 5.2


(原文件名:error.JPG)

出0入0汤圆

 楼主| 发表于 2010-11-20 11:52:11 | 显示全部楼层
有高版本IAR的朋友试一下
工程包

出0入0汤圆

 楼主| 发表于 2010-11-20 11:52:45 | 显示全部楼层
点击此处下载 ourdev_599230IP68UV.rar(文件大小:15K) (原文件名:test.rar)

工程包

出0入0汤圆

 楼主| 发表于 2010-11-20 11:53:46 | 显示全部楼层
难道IAR不能用指针类型强制转换?!

出0入0汤圆

发表于 2010-11-20 16:38:32 | 显示全部楼层
pa = &a;就可以了,不需要强制类型转换

void*可以接受任意类型指针

出0入0汤圆

发表于 2010-11-20 16:39:49 | 显示全部楼层
这个没必要追求真正的解,编译器本来就不符合C标准。找到个能用的方法就行。另外提一句,void *声明的指针比普通指针多一字节。
unsigned short * 2字节
void *

出0入0汤圆

发表于 2010-11-20 16:40:04 | 显示全部楼层
这个没必要追求真正的解,编译器本来就不符合C标准。找到个能用的方法就行。另外提一句,void *声明的指针比普通指针多一字节。
unsigned short * 2字节
void *           3字节
我在keil 8.04试验,代码完全没问题

(原文件名:QQ拼音截图未命名.png)

出0入0汤圆

发表于 2010-11-20 16:45:56 | 显示全部楼层
void*多一字节....-_-

keil编译器果然不是一般的非标呀

出0入0汤圆

 楼主| 发表于 2010-11-20 19:31:59 | 显示全部楼层
回复【27楼】shamork 氧化还原合成单片机
-----------------------------------------------------------------------

指针都是4个字节吧

出0入0汤圆

发表于 2010-11-22 15:21:33 | 显示全部楼层
回复【29楼】McuY
回复【27楼】shamork 氧化还原合成单片机
-----------------------------------------------------------------------
指针都是4个字节吧
-----------------------------------------------------------------------

普通带类型的指针
unsigned char *
unsigned short *
unsigned int *
unsigned long *
如果存储类型为xdata idata bdata xdata 统统2字节。就是说,类型已经确定了,指针仅仅是一个0-0xFFFF的地址
如果是void *,那么多出一个字节来存储指针类型,每次进行操作,将可能改变指针的类型

出0入0汤圆

发表于 2011-4-7 19:12:11 | 显示全部楼层
回复【8楼】dengxiaofeng 天下的人
我来说说吧  
指针本身是没什么数据类型的  因为指针本身存储的就是个地址  地址 的类型都是一样的  
因此 在定义指针时的类型是指   该指针指向数据的类型,比如 要定义一个 int型的数 就要  int *pa;如果定义一个指向
unsigned char 类型的数  那么就要定义一个  unsigned char *pa;
-----------------------------------------------------------------------

正解,完全同意!
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-6-3 19:05

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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