1

我一直认为 *&p = p = &*p 在 C 中。我尝试了以下代码:

 #include <stdio.h>
 #include <stdlib.h>

 char a[] = "programming";
 char *ap = &a[4];  

int main(void)
{

 printf("%x %x %x\n", ap, &*(ap), *&(ap));   /* line 13 */
 printf("%x %x %x\n\n", ap+1, &*(ap+1), *&(ap+1));   /* line 14 */
}

第一个 printf 行(第 13 行)给了我地址:

40b0a8 40b0a8 40b0a8

这与预期的相同。但是当我添加第二行 printf 时,Borland 抱怨道:

“first.c”:E2027 必须在第 14 行的函数 main 中获取内存位置的地址

我期待得到:

40b0a9 40b0a9 40b0a9。

似乎第 14 行的表达式 *&(ap+1) 是这里的罪魁祸首。我认为第 14 行的所有三个指针表达式都是等价的。为什么我想错了?

第二个相关问题:线

char *ap = a;

指向数组 a 的第一个元素。我用了

char *ap = &a[4];  

指向数组 a 的第 5 个元素。

是表达式

char *ap = a;

和表达式一样

char *ap = &a[0];

最后一个表达式是否比前一个表达式更冗长?

非常感谢...

4

4 回答 4

6

您只能获取左值的地址,即引用对象的表达式。ap + 1是地址计算。它有一个值,但它是一个临时对象,因此不是左值,您不能获取它的地址。

在回答你的第二个问题时,在表达式中的大多数上下文中,数组衰减到指向它的第一个元素的指针,所以是的,char *ap = a;并且char *ap = &a[0];是等价的。

于 2010-04-11T21:45:18.500 回答
1

当您使用 C 引用运算符时,它必须指向一个有效的左值,而不是任意表达式。因此,&(ap+1)无效,因为该值ap+1只是一个表达式,而不是一个位置。你不能说ap+1 = foo();

是的,这里的 a 与 &a[0] 相同。请注意,*(a+b) 与 a[b] 100% 等价(有关此等价的不寻常示例,请参阅Strangest language feature的最佳答案)。获取指向数组成员的指针时,可以使用 &array[i] 或 array + i。例子:

struct foo array[5];
struct foo *item_3 = &array[3];
struct foo *also_item_3 = array + 3;

在这种情况下,是否使用array+i还是&array[i]风格问题。 &array[i]可以说是一个更好的选择,因为更清楚的是正在获取数组项。此外,&vec[i] 适用于 C++ 的向量,而 vec+i 不适用。

于 2010-04-11T21:52:49.530 回答
0

如果您认为其中一个语句是罪魁祸首,我会将该行分成三个单独的行,并查看编译器在哪里向您抱怨。我也有同样的怀疑,但为了证实这一点,我会照我刚才告诉你的去做。

于 2010-04-11T21:45:29.843 回答
0

我相信查尔斯对你的主要问题是正确的,你对第二个问题是正确的:char *ap = a;相当于char *ap = &a[0];.

于 2010-04-11T21:50:08.647 回答