取消引用二维的名称与名称相同。那么dereference做什么呢?

时间:2014-03-25 15:14:25

标签: c pointers

取消引用有什么作用? 它只是返回指针中的地址值。

WIKI说"它对指针变量进行操作,并返回一个等于指针地址"

的值的l值

我对以下代码感到困惑:

int p[2][2] = {1, 2, 3, 4};
printf("%p\t%p", p, *p);

我知道p是一个指向数组的指针,就像这个

int (*p)[2];

假设p的地址为0x003DEF4C。那么* p不应该是0x003DEF4C中的值吗? 但它与p具有相同的价值。

所以它喜欢取消引用而不只是返回指针所指向的地址的值。

3 个答案:

答案 0 :(得分:1)

维基说什么是真实而且非常简单。从一维数组开始

int p[4] = {1, 2, 3, 4};
printf("%p\t%d", (void *)p, *p);

p转换为指向数组p[]的第一个元素的指针。取消引用p将返回存储在地址p点的值。 *p是一个l值,相当于变量p[0] 以简单作业为例;

p[0] = 5;         // In this assignment p[0] is a l-value
*p   = p[0] + 1;  // p[0] is r-value and *p is l-value 
p[0] = *p - 5;    // p[0] is l-value and *p is r-value 

答案 1 :(得分:1)

  

取消引用有什么作用?它只是在指针中返回地址的值吗?

当您取消引用指针时,您将获得指针指向的值。

  

假设p的地址为0x003DEF4C。所以* p不应该是0x003DEF4C中的值?但它与p具有相同的价值。

对于您拥有的特定代码,这是正确的。看看与你的有点不同的东西。

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

int main()
{
   int p1[2][2] = {1, 2, 3, 4};
   int* p2[2] = {NULL, NULL};
   int** p3 = NULL;
   int** p4 = NULL;

   p2[0] = (int*)malloc(2*sizeof(int));
   p2[1] = (int*)malloc(2*sizeof(int));
   p2[0][0] = 1;
   p2[0][1] = 2;
   p2[1][0] = 3;
   p2[1][1] = 4;

   p3 = (int**)malloc(2*sizeof(int*));

   p3[0] = (int*)malloc(2*sizeof(int));
   p3[1] = (int*)malloc(2*sizeof(int));
   p3[0][0] = 1;
   p3[0][1] = 2;
   p3[1][0] = 3;
   p3[1][1] = 4;

   p4 = (int**)malloc(4*sizeof(int));
   p4[0] = (int*)p4;
   p4[1] = p4[0]+2;
   p3[0][0] = 1;
   p3[0][1] = 2;
   p3[1][0] = 3;
   p3[1][1] = 4;

   printf("Address of p1:    %p\n", (void*)p1);
   printf("Address of p1[0]: %p\n", (void*)p1[0]);
   printf("Address of p1[1]: %p\n", (void*)p1[1]);
   printf("\n");

   printf("Address of p2:    %p\n", (void*)p2);
   printf("Address of p2[0]: %p\n", (void*)p2[0]);
   printf("Address of p2[1]: %p\n", (void*)p2[1]);
   printf("\n");

   printf("Address of p3:    %p\n", (void*)p3);
   printf("Address of p3[0]: %p\n", (void*)p3[0]);
   printf("Address of p3[1]: %p\n", (void*)p3[1]);
   printf("\n");

   printf("Address of p4:    %p\n", (void*)p4);
   printf("Address of p4[0]: %p\n", (void*)p4[0]);
   printf("Address of p4[1]: %p\n", (void*)p4[1]);
   printf("\n");

   /* Add code to free the allocated memory */
}

p1,它定义的所有内容都是使用堆栈上的内存创建的。 p1指向的地址等于p1[0]指向的地址。它们都指向堆栈中的地址。

使用堆栈上的内存创建

p2p2[0]p2[1]p2指向堆栈内存中的地址。但是,为p2[0]p2[1]分配的内存来自堆。 p2指向的地址与地址p2[0]指向的地址不同。

在堆栈上创建了

p3,但它指向的地址是从堆中创建的。地址p3[0]指向的地址也是从堆中创建的。由于它们是使用对malloc的单独调用创建的,因此它们指向不同的地址。

p4是一个示例,说明如何操作从堆分配的连续内存以满足您自己的需要。因为我们知道我们需要存储4个整数,所以我们可以为它们分配内存并确保我们的指针指向正确的位置。操作p4的堆内存类似于编译器在堆栈上创建所有内容时的操作。

这是我运行程序时的示例输出:

./test-22
Address of p1:    0x28ac18
Address of p1[0]: 0x28ac18
Address of p1[1]: 0x28ac20

Address of p2:    0x28ac10
Address of p2[0]: 0x80010458
Address of p2[1]: 0x80010468

Address of p3:    0x80010478
Address of p3[0]: 0x80010488
Address of p3[1]: 0x80010498

Address of p4:    0x800104a8
Address of p4[0]: 0x800104a8
Address of p4[1]: 0x800104b0

答案 2 :(得分:0)

printf中,您要求:

  • p:二维数组的地址=数组第一个元素的地址
  • *p:1维子数组的地址=数组第1个元素的地址(与上面的地址相同)

请注意,如果你查看(*p)[1]的地址(例如第二个子阵列),你应该有不同的东西。