指针索引

huangapple go评论63阅读模式
英文:

Index of pointer

问题

在下面的代码中,我将变量 var 设置为 20,然后将指针 ptr 设置为指向 var 的地址。然后,将指针 ptrptr 设置为保存指针 ptr 的内存地址。

#include <stdio.h>;

void pointers()
{
	int var = 20;
	int* ptr;
	ptr = &var;

    int *ptrptr = ptr;

	printf("ptrptr[0] 所指的值 = %d \n", ptrptr[0]);
}

// 主程序
int main()
{
	pointers();
	return 0;
}

输出:

ptrptr[0] 所指的值 = 20

为什么 ptrptr[0] 返回存储在 var 中的值,而不是指针 ptr 的内存地址呢?

我认为索引运算符 [] 返回存储在该位置的值。

英文:

In the code below I set the variable var to 20, then the pointer ptr to the address of var. Then the pointer ptrptr to hold the memory address of the pointer ptr.

#include &lt;stdio.h&gt;

void pointers()
{
	int var = 20;
	int* ptr;
	ptr = &amp;var;

    int *ptrptr = ptr;

	printf(&quot;Value at ptrptr[0] = %d \n&quot;, ptrptr[0]);
}

// Driver program
int main()
{
	pointers();
	return 0;
}

Output:

Value at ptrptr[0] = 20

Why does ptrptr[0] return the value stored by val, and not the memory address of the pointer ptr.

I thought that the indexing operator [] returns the value stored by that value.

答案1

得分: 6

这是一个示例,希望能更清楚地说明正在发生什么。

#include <stdio.h>

int main()
{
    int var = 20;
    int *ptr = &var;
    int *ptr2 = ptr;

    printf("变量var的值是 %d\n", var);
    printf("变量var的地址是 %p\n\n", &var);

    printf("指针ptr的值是 %p\n", ptr);
    printf("ptr指向的值是 %d\n", *ptr);
    printf("或者,另一种说法是 %d\n\n", ptr[0]);

    printf("指针ptr2的值是 %p\n", ptr2);
    printf("ptr2指向的值是 %d\n", *ptr2);
}

在我的机器上,这将打印:

变量var的值是 20
变量var的地址是 0x7ffeed56992c

指针ptr的值是 0x7ffeed56992c
ptr指向的值是 20
或者,另一种说法是 20

指针ptr2的值是 0x7ffeed56992c
ptr2指向的值是 20


由于`ptr`和`ptr2`具有相同的类型(`int *`),并且由于它们持有相同的指针值(因为我们说过`ptr2 = ptr`),它们的行为相同。

由于在C中存在“数组和指针之间的对应关系”,`*ptr`与`ptr[0]`是相同的。这两个表达式都产生指向`ptr`指向的值。

如果您使用`ptrptr`的意图是使它成为一个指向指针的指针,以下是该细节的说明。由于`ptrptr`是一个二级指针,其指向的值实际上是另一个指针,因此您必须非常小心地思考它。

```c
int **ptrptr = &ptr;
printf("指针ptrptr的值是 %p\n", ptrptr);
printf("ptrptr指向的值是 %p\n", *ptrptr);
printf("而由该指针指向的值是 %d\n", **ptrptr);

这还会额外打印:

指针ptrptr的值是 0x7ffeed569920
ptrptr指向的值是 0x7ffeed56992c
而由该指针指向的值是 20
英文:

Here is an example which will, I hope, make it more clear what's going on.

#include &lt;stdio.h&gt;

int main()
{
    int var = 20;
    int *ptr = &amp;var;
    int *ptr2 = ptr;

    printf(&quot;the value of the variable var is %d\n&quot;, var);
    printf(&quot;the address of the variable var is %p\n\n&quot;, &amp;var);

    printf(&quot;the value of the pointer ptr is %p\n&quot;, ptr);
    printf(&quot;the value pointed to by ptr is %d\n&quot;, *ptr);
    printf(&quot;or, stated another way, it&#39;s %d\n\n&quot;, ptr[0]);

    printf(&quot;the value of the pointer ptr2 is %p\n&quot;, ptr2);
    printf(&quot;the value pointed to by ptr2 is %d\n&quot;, *ptr2);
}

On my machine this prints:

the value of the variable var is 20
the address of the variable var is 0x7ffeed56992c

the value of the pointer ptr is 0x7ffeed56992c
the value pointed to by ptr is 20
or, stated another way, it&#39;s 20

the value of the pointer ptr2 is 0x7ffeed56992c
the value pointed to by ptr2 is 20

Since ptr and ptr2 have the same type (int *), and since they hold the same pointer value (since we said ptr2 = ptr), they behave the same.

And because of the "correspondence between arrays and pointers" in C, *ptr is identical to ptr[0]. Both expressions yield the value pointed to by ptr.

If your intention with ptrptr was to have it be a pointer to a pointer, here's an illustration of that wrinkle. Since ptrptr is a two-level pointer, its pointed-to value is actually another pointer, so you have to be really careful thinking about it.

int **ptrptr = &amp;ptr;
printf(&quot;the value of the pointer ptrptr is %p\n&quot;, ptrptr);
printf(&quot;the value pointed to by ptrptr is %p\n&quot;, *ptrptr);
printf(&quot;and the value pointed to by that pointer is %d\n&quot;, **ptrptr);

This additionally prints:

the value of the pointer ptrptr is 0x7ffeed569920
the value pointed to by ptrptr is 0x7ffeed56992c
and the value pointed to by that pointer is 20

答案2

得分: 4

根据定义 *(ptr + n) === ptr[n]

为什么 ptrptr[0] 返回 val 存储的值,而不是指针 ptr 的内存地址。

我认为索引操作符 [] 返回存储在那个值中的值。

没有 ptr[x] 解引用指针。

int x = 5;
int *ptr = &x;
int *ptrptr = ptr; //这将引用存储在 ptr 中的引用分配给 ptrptr。现在它们存储相同的引用。

printf("解引用指针 - %d\n", ptr[0]);
printf("指针中存储的引用 - %p\n", (void *)ptr);
printf("指针的引用(其地址) - %p\n", (void *)&ptr);

根据您的第二个指针的名称,您可能想要指向指针的指针

int x = 5;
int *ptr = &x;
int **ptrptr = &ptr; //指向指针的指针

printf("解引用指针到指针 - x 的引用 %p\n", (void *)ptrptr[0]);
printf("指向指针的指针中存储的引用 - ptr 的引用 %p\n", (void *)ptrptr);
printf("指针的引用(其地址) - %p\n", (void *)&ptrptr);
英文:

By definition *(ptr + n) === ptr[n]

> Why does ptrptr[0] return the value stored by val, and not the memory
> address of the pointer ptr.
>
> I thought that the indexing operator [] returns the value stored by
> that value.

no ptr[x] dereferences the pointer.

int x = 5;
int *ptr = &amp;x;
int *ptrptr = ptr; //this assigns reference stored in ptr to ptrptr. Now they store the same reference.

printf(&quot;Dereferencing pointer - %d\n&quot;, ptr[0]);
printf(&quot;Reference stored in the pointer - %p\n&quot;, (void *)ptr);
printf(&quot;Reference of the pointer (its address) - %p\n&quot;, (void *)&amp;ptr);

Judging from the name of your second pointer you probably wanted pointer to pointer

int x = 5;
int *ptr = &amp;x;
int **ptrptr = &amp;ptr; //poiter to pointer

printf(&quot;Dereferencing pointer to pointer - reference of x %p\n&quot;, (void *)ptrptr[0]);
printf(&quot;Reference stored in the pointer to pointer - reference of ptr%p\n&quot;, (void *)ptrptr);
printf(&quot;Reference of the pointer (its address) - %p\n&quot;, (void *)&amp;ptrptr);

答案3

得分: 3

ptrptr[0]

与(因为ptrptrptr是相同类型且具有相同值)相同:

ptr[0]

与(因为a[b] == *(a+b))相同:

*ptr

var相同,因为ptr指向var,而*ptr是对指针的解引用。

var的值为20

英文:

This

ptrptr[0]

is the same as (because ptrptr and ptr are same type and have same value):

ptr[0]

is the same as (because a[b] == *(a+b)):

*ptr

is the same as var, because ptr points to var, and *ptr is dereferencing the pointer.

The value of var is 20.

答案4

得分: 2

ptrptr 的类型与 ptr 相同,都是指向 int 的指针。因此,当你执行 int *ptrptr = ptr; 时,现在 ptrptrptr 指向相同的地址(这就是为什么它能够编译通过的原因)。此外,ptrptr[0]*ptrptr 是相同的。

如果你想让 ptrptr 指向 ptr,你必须将 ptrptr 定义为指向 int 的指针的指针:

int **ptrptr = &ptr;
printf("Value at ptrptr[0] = %d \n", *ptrptr[0]);

编译器浏览器链接

英文:

ptrptr has the same type as ptr, a pointer to an int. So when you do int *ptrptr = ptr;, now ptrptr and ptr point to the same address (that's why it compiles as well). Also ptrptr[0] is the same as to *ptrptr

You have to define ptrptr to be a pointer to a pointer of an int:

int **ptrptr = &amp;ptr;
printf(&quot;Value at ptrptr[0] = %d \n&quot;, *ptrptr[0]);

if you wanted ptrptr to point to ptr

Link to Compiler Explorer.

答案5

得分: 1

You never set ptrptr to hold the memory address of ptr but to the value of ptr itself. Below is an image for illustration. First ptr is assigned the address of var and then ptrptr is assigned the value of ptr, so it also points to var.

指针索引

To make ptrptr point to ptr you need to declare it as

int **ptrptr = &ptr;

指针索引

英文:

You never set ptrptr to hold the memory address of ptr but to the value of ptr itself. Below is an image for illustration. First ptr is assigned the address of var and then ptrptr is assigned the value of ptr, so it also points to var.

指针索引

To make ptrptr point to ptr you need to declare it as

int **ptrptr = &amp;ptr;

指针索引

huangapple
  • 本文由 发表于 2023年2月8日 21:40:07
  • 转载请务必保留本文链接:https://go.coder-hub.com/75386636.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定