我一直以为*& p = p =& * p in 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行的表达式*&amp;(ap + 1)是罪魁祸首。我认为第14行的所有三个指针表达式都是等价的。为什么我错了?
第二个相关问题:第
行char *ap = a;
指向数组a的第一个元素。我用了
char *ap = &a[4];
指向数组a的第5个元素。
是表达式
char *ap = a;
与表达式
相同char *ap = &a[0];
最后一个表达式是否比前一个表达式更详细?
非常感谢...
答案 0 :(得分:6)
您只能获取左值的地址,即引用对象的表达式。 ap + 1
是地址计算。它有一个值,但它是一个临时对象,所以不是左值,你不能取其地址。
在回答你的第二个问题时,在表达式的大多数情况下,数组会衰减到指向它的第一个元素的指针,所以是的,char *ap = a;
和char *ap = &a[0];
是等价的。
答案 1 :(得分:1)
使用C引用运算符时,它必须指向有效的左值,而不是任意表达式。因此,&(ap+1)
无效,因为值ap+1
只是表达式,而不是位置。你不能说ap+1 = foo();
是的,a和这里的&amp; a [0]相同。请注意,*(a + b)与[b] 100%等效(请参阅Strangest language feature的最佳答案,了解此等效的一个不寻常的例子)。获取指向数组成员的指针时,可以使用&amp; 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]
可以说是一个更好的选择,因为更清楚的是获得了一个数组项。此外,&amp; vec [i]使用C ++的向量,而vec + i则不然。
答案 2 :(得分:0)
如果您认为其中一个陈述是具体的罪魁祸首,我会将该行分成三行,并查看编译器向您抱怨的位置。我也有同样的怀疑,但为了证实这一点,我会像刚刚告诉你的那样做。
答案 3 :(得分:0)
我相信Charles对您的主要问题是正确的,并且您对第二个问题是正确的:char *ap = a;
相当于char *ap = &a[0];
。