有人可能会向我解释,在以下两行代码中发生了什么?假设我们在32位计算机上工作指针算术问题
p - 为指针
(*(long *)((char **)(p) - 1))
(*(int *)((int)(p) - 4))
我了解的唯一的事情,就是*(long *)
“东西”转换为long
类型的指针,然后DEREF。获得价值。
谢谢!
有人可能会向我解释,在以下两行代码中发生了什么?假设我们在32位计算机上工作指针算术问题
p - 为指针
(*(long *)((char **)(p) - 1))
(*(int *)((int)(p) - 4))
我了解的唯一的事情,就是*(long *)
“东西”转换为long
类型的指针,然后DEREF。获得价值。
谢谢!
(*(long *)((char **)(p) - 1))
开始与指针p。将其转换为类型(char **)。从中减去一个。将结果转换为类型(long *),然后取消引用结果。换句话说,将指针移动一个字节,并获取存储在该地址的长整型值。这个操作在某些平台上可能会被打破,特别是取决于p的类型。
(*(int *)((int)(p) - 4))
从指针p开始。将其转换为int。减去4.将它转换为(int *),并取消引用结果。现在,不是做正常的指针算术,而是直接将指针值作为整数进行摆动,将其移位四位,然后读取结果指向的int。该操作在某些系统上也会被打破。
我觉得我设法解析,而不会迷失在parens。无论如何,不要这样做。这是病态的。可能有一些奇怪的嵌入式开发任务,你认为这样的事情是一个好主意。如果是这样,永远不要承认已经做到了。如果发现它,就责怪别人。
例如,与第二实施例,其中p为一个int *,并用8个字符和32位整数的系统上,你基本上完成*(P-1)
OTOH,在一个一台16位int的机器,你正在执行*(p-2),并且在一台64位int的机器上,你正在执行*(p-0.5),这是不明智的,并且可能会崩溃而只是抱怨关于未对齐的内存访问。 (它应该会崩溃。)使用实际指向正确类型的指针,并且你永远不应该有理由去做这种无稽之谈。
我刚刚注意到我的第一个描述是错误的。从char **减1会调整指针的sizeof(char *)而不是sizeof(char)。所以,如我所说,偏移量可能大于一个字符的大小。 (虽然从技术上来说,一个char可以和char *一样......) – wrosecrans 2010-12-16 07:48:39
(*(long *)((char **)(p) - 1))
Looks like getting the length of some kind of length byte character array
that was passed by reference. But that is just first glance..
(p) = some object
(char **) casts some object to the address of the address of a character, which is a 32bit value sizeof(char**)
-1 gets the 32bits in memory prior to (char **)(p)
*(long*) does what you thought, takes that 32bits, casts it as a long *, and dereferences it.
So there is a record in memory like:
struct {long * n; char ** s; }
similiar to what happens in parameter passing.
(*为(int *)((int)的(P) - 4))
这一个是难看。一些对象p被转换为一个int,让我们希望sizeof(int)是32,所以它可能是一个地址,从它减去4(地址仍然是计数字节,4字节是32位),将其作为指向int ,并将其解除引用。
对于额外的信用比较它: *((INT *)((INT)(P)) - 1)
1: ((字符**)(P) - 1):投p来指向字符的数组的数组和减去(所以它现在就像& P [-1])
(长*):将它转换为指向long的指针,并且从该地址开始持续很长时间。
2: ((int)的(P) - 4):投p存放和减去4
(INT *):投它指向INT的阵列,并从该地址
INT取首先得到p
之前很久。
对于X32的sizeof(字符*)==的sizeof(长),所以(长*)(字符* )为(长)
所以它只是*((long*)p - 1 )
或((long*)p)[-1]
第二行则是相同的,但它产生int
而不是long
。 (long*)p - 1
是相同的地址作为(int)p - 4
,因为的sizeof(长)== 4.
考虑p是一个指针,指向二维阵列 为.eg
int a[][5] = {10,20,30,40,50,11,21,31,41,51,12,22,32,42,52,13,23,33,43,53,14,24,34,44,54};
int (*p)[5] = a;
现在为了简单起见,我们假设地址的[0] [0]作为1000
现在让我们评估(*(long *)((char **)(p) + 1));
(char **)(p)
会给你解决[0] [0] >>>>即1000(char **)(p) + 1
会的sizeof INT添加到您的地址>>>>即1004(*(long *)((char **)(p) + 1));
将在我们的例子
评估到20我就希望* *,这是一个32位的机器上。该代码是64位不安全的。 – 2010-12-16 05:48:24
'p'是什么?[MoreCharactersToAppeaseJeffAtwood] – 2010-12-16 05:48:31
根据'p'的类型可能是ub也可能不是ub。 – wilhelmtell 2010-12-16 05:48:52