C 指针和地址

发布于 2024-08-28 15:38:16 字数 951 浏览 12 评论 0原文

我一直认为 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

阳光下的泡沫是彩色的 2024-09-04 15:38:16

您只能获取左值的地址,即引用对象的表达式。 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; and char *ap = &a[0]; are equivalent.

温折酒 2024-09-04 15:38:16

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

是的,a 与这里的 &a[0] 相同。请注意, *(a+b) 100% 相当于 a[b] (请参阅 最奇怪的语言功能的最佳答案 是这种等价的一个不寻常的例子)。当获取指向数组成员的指针时,可以使用 &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 则不行。

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 value ap+1 is simply an expression, not a location. You can't say ap+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:

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

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.

青春如此纠结 2024-09-04 15:38:16

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

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.

眼中杀气 2024-09-04 15:38:16

我相信 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 to char *ap = &a[0];.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文