C 指针和地址
我一直认为 C 中的 *&p = p = &*p 。我尝试了这段代码:
#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];
吗最后一个表达式只是比前一个表达式更详细?
多谢...
I always thought that *&p = p = &*p in C. I tried this code:
#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 */
}
The first printf line (line 13) gives me the addresses:
40b0a8 40b0a8 40b0a8
which are the same as expected. But when I added the second printf line, Borland complains:
"first.c": E2027 Must take address of a memory location in function main at line 14
I was expecting to get:
40b0a9 40b0a9 40b0a9.
It seems that the expression *&(ap+1) on line 14 is the culprit here. I thought all three pointer expressions on line 14 are equivalent. Why am I thinking wrong?
A second related question: The line
char *ap = a;
points to the first element of array a. I used
char *ap = &a[4];
to point to the 5th element of array a.
Is the expression
char *ap = a;
same as the expression
char *ap = &a[0];
Is the last expression only more verbose than the previous one?
Thanks a lot...
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
您只能获取左值的地址,即引用对象的表达式。
ap + 1
是地址计算。它有一个值,但它是一个临时对象,因此不是左值,并且您无法获取它的地址。在回答你的第二个问题时,在表达式的大多数上下文中,数组会衰减为指向其第一个元素的指针,所以是的,
char *ap = a;
和char *ap = &a[ 0];
是等效的。You can only take the address of an lvalue, i.e. an expression that refers to an object.
ap + 1
is an address calculation. It has a value but it's a temporary object so isn't an lvalue and you can't take its address.In answer to your second question, in most contexts in expressions an array decays to a pointer to it's first element so yes,
char *ap = a;
andchar *ap = &a[0];
are equivalent.当您使用 C 引用运算符时,它必须指向有效的左值,而不是任意表达式。因此,
&(ap+1)
无效,因为值ap+1
只是一个表达式,而不是位置。你不能说ap+1 = foo();
是的,a 与这里的 &a[0] 相同。请注意, *(a+b) 100% 相当于 a[b] (请参阅 最奇怪的语言功能的最佳答案 是这种等价的一个不寻常的例子)。当获取指向数组成员的指针时,可以使用 &array[i] 或 array + i。示例:
在本例中,使用
array+i
还是&array[i]
是风格问题。&array[i]
可以说是更好的选择,因为更清楚的是正在获取数组项。此外,&vec[i] 适用于 C++ 的向量,而 vec+i 则不行。When you use the C reference operator, it has to point to a valid lvalue, not an arbitrary expression. Thus,
&(ap+1)
isn't valid because the valueap+1
is simply an expression, not a location. You can't sayap+1 = foo();
And yes, a is the same as &a[0] here. Note that *(a+b) is 100% equivalent to a[b] (see the top answer to Strangest language feature for an unusual example of this equivalence). When getting a pointer to a member of an array, you can use &array[i] or array + i. Example:
In this case, whether to use
array+i
or&array[i]
is a matter of style.&array[i]
is arguably a better choice, as it is clearer that an array item is being gotten. Moreover, &vec[i] works with C++'s vectors, whereas vec+i does not.如果您认为其中一个语句是罪魁祸首,我会将该行分成三行,看看编译器在哪里向您抱怨。我也有同样的怀疑,但为了证实这一点,我会按照我刚才告诉你的去做。
If you believe one of those statements is the culprit specifically, I would break that line into three separate lines and see where the compiler complains at you. I bear the same suspicion, but to confirm it I would do just as I just told you to do.
我相信 Charles 关于您的主要问题是正确的,您对第二个问题也是正确的:
char *ap = a;
相当于char *ap = &a[0];< /代码>。
I believe Charles is correct about your main question, and you are correct about the second question:
char *ap = a;
is equivalent tochar *ap = &a[0];
.