指针算术 [英] pointers arithmetics

查看:68
本文介绍了指针算术的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请帮我指点。


我有一个基指针,说它是一个0x06000000并且从它偏移到

寄存器(例如,#define REG1 0x04)。我正在以下列方式访问他们。


void * base = MEMBASE; / * 0x06000000 * /

uint32_t val = 0;


val =((uint32_t)*(base + REG1));

/ *做val * /

((uint32_t)*(base + REG1))= val;


这段代码是否正确?我不确定因为sizeof(void *)= 4,所以(base + 4)

将是(base + 4 *(sizeof(void *))),这将指向我不正确的

地址。如果是真的,那么正确的方法是什么?


提前致谢。


-

s /.../。gotovchits / g发送电子邮件。

解决方案

Ivan Gotovchits说:


请帮我指点。


我有一个基本指针,说它是一个0x06000000并且从它偏移到

寄存器(例如,#define REG1 0x04)。我正在以下列方式访问他们。


void * base = MEMBASE; / * 0x06000000 * /

uint32_t val = 0;


val =((uint32_t)*(base + REG1));

/ *做val * /

((uint32_t)*(base + REG1))= val;


这段代码是否正确?



不,它不是。代码对void *执行算术,这是不合法的

C.此外,演员的结果不是可修改的左值,所以它不能是左边的b $ b赋值语句的操作数。


我不确定因为sizeof(void *)= 4,所以(base +

4 )将是(base + 4 *(sizeof(void *))),



否,即使sizeof(void *)为4,这也没有任何意义到

表达式(基数+4)。当你将N添加到P(其中P是指向某些

对象类型的指针)时,结果是指向N个对象超过P的指针值,

其中大小通过计算P指向的对象的大小来确定对象的大小。由于当P为void *类型时,不能将这个对象的大小当作对象的大小,因此计算是非法的。


将指向我到

不正确的地址。如果是真的,那么正确的方法是什么?



嗯,没有正确的方法,但有不正确的方法!

也就是说,当您执行以下操作时,C标准不会对将要发生的事情做出任何保证




#define MEMBASE(void *)0x06000000UL


void * base = MEMBASE; / * 0x06000000 * /

unsigned char * ucbase = base;

uint32_t val = 0;


val = *(uint32_t )(ucbase + REG1);

/ *做一些val * /

*(uint32_t)(base + REG1)= val;


但它确实至少有一个战斗机会按照你的预期工作
*一些*(但绝不是全部)实现。


-

Richard Heathfield< http://www.cpax.org.uk>

电子邮件:-http:// www。 + rjh @

谷歌用户:< http://www.cpax.org.uk/prg/writings/googly.php>

Usenet是一个奇怪的放置" - dmr 1999年7月29日


>我有一个基本指针,说它是一个0x06000000并且从它偏移到


>寄存器(例如,#define REG1 0x04)。我正在以下列方式访问他们。

void * base = MEMBASE; / * 0x06000000 * /
uint32_t val = 0;

val =((uint32_t)*(base + REG1));



不要尝试对void *指针进行数学运算。


> / * do val * /
((uint32_t)*(base + REG1))= val;

这段代码是否正确?我不确定因为sizeof(void *)= 4,



可能是真的,但这与这种情况无关。
< blockquote class =post_quotes>
> so(base + 4)
将是(base + 4 *(sizeof(void *))),



不,实际上是'(基数加4 mul(sizeof(void *))),使用

汇编语言运算符而不是C运算符。那是'拣货

nits,但这是一个重要的区别。


不,sizeof(void)没有定义,所以(base +) 4)可能是任何东西。


>这将指向我不正确的
地址。如果是真的,那么正确的方法是什么?



你想用什么单位用于REG1?也许你的指针

应该是char *。


Gordon Burditt写道:


不要尝试对void *指针进行数学运算。



是的,它甚至无法编译......


你想用什么单位用于REG1?也许你的指针

应该是char *。



我在地址库中有一个32位寄存器+ 0x04(即如果基数为0x06000000,那么
则会在地址处找到reg 0x06000004)


-

s /.../。gotovchits / g for email。


Please, help me with the pointers.

I''ve a base pointer, say it is a 0x06000000 and offsets from it to
registers (for example, #define REG1 0x04). I''m accessing to them in a
following way.

void *base = MEMBASE; /* 0x06000000 */
uint32_t val = 0;

val = ((uint32_t) *(base + REG1));
/* do something with val */
((uint32_t) *(base + REG1)) = val;

Is this code correct? I''m not sure because sizeof(void *) = 4, so (base + 4)
will be (base + 4 * (sizeof(void *))), that will point me to the incorrect
address. If it is true, then what will be the correct method?

Thanks in advance.

--
s/.../.gotovchits/g for email.

解决方案

Ivan Gotovchits said:

Please, help me with the pointers.

I''ve a base pointer, say it is a 0x06000000 and offsets from it to
registers (for example, #define REG1 0x04). I''m accessing to them in a
following way.

void *base = MEMBASE; /* 0x06000000 */
uint32_t val = 0;

val = ((uint32_t) *(base + REG1));
/* do something with val */
((uint32_t) *(base + REG1)) = val;

Is this code correct?

No, it''s not. The code performs arithmetic on a void *, which is not legal
C. Furthermore, the result of a cast is not a modifiable lvalue, so it
cannot be the left operand of an assignment statement.

I''m not sure because sizeof(void *) = 4, so (base +
4) will be (base + 4 * (sizeof(void *))),

No, even if sizeof(void *) is 4, this is of no consequence to the
expression (base + 4). When you add N to P (where P is a pointer to some
object type), the result is a pointer value that points N objects past P,
where the size of the object is determined by computing the size of the
kind of object to which P points. Since one cannot take the size of such
an object when P is of type void *, the calculation is illegal.

that will point me to the
incorrect address. If it is true, then what will be the correct method?

Well, there isn''t a "correct" method, but there are less incorrect methods!
That is, the C Standard doesn''t make any guarantees about what will happen
when you do the following:

#define MEMBASE (void *)0x06000000UL

void *base = MEMBASE; /* 0x06000000 */
unsigned char *ucbase = base;
uint32_t val = 0;

val = *(uint32_t)(ucbase + REG1);
/* do something with val */
*(uint32_t)(base + REG1) = val;

but it does at least have a fighting chance of working as you expect on
*some* (but by no means all) implementations.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999


>I''ve a base pointer, say it is a 0x06000000 and offsets from it to

>registers (for example, #define REG1 0x04). I''m accessing to them in a
following way.

void *base = MEMBASE; /* 0x06000000 */
uint32_t val = 0;

val = ((uint32_t) *(base + REG1));

Don''t try to do math on void* pointers.

>/* do something with val */
((uint32_t) *(base + REG1)) = val;

Is this code correct? I''m not sure because sizeof(void *) = 4,

Could be true but it''s not relevant to this situation.

>so (base + 4)
will be (base + 4 * (sizeof(void *))),

No, actually that''s (base add 4 mul (sizeof(void *))), using
assembly-language operators instead of C operators. That''s picking
nits, but it''s an important distinction.

No, sizeof(void) is not defined, so (base + 4) might be anything.

>that will point me to the incorrect
address. If it is true, then what will be the correct method?

What units are you trying to use for REG1? Maybe your pointer
should be char *.


Gordon Burditt wrote:

Don''t try to do math on void* pointers.

Yes, really it even fails to compile ...

What units are you trying to use for REG1? Maybe your pointer
should be char *.

I have a 32 bit register at the address base + 0x04 (i.e if base 0x06000000,
then reg will be found at the address 0x06000004)

--
s/.../.gotovchits/g for email.


这篇关于指针算术的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆