指针变量的大小被存储在哪里?

问题描述:

#include <stdio.h> 

int main(void) 
{ 
int a[5]={1,2,3,4,5}; 
int *ptr=(int*)(&a+1); 
printf("%d %d\n",*(a+1),*(ptr-1)); 
return 0; 
} 

输出:指针变量的大小被存储在哪里?

2 5 

在这里,在声明*ptr= (int*)(&a+1) 1不添加到&a。其实它就像&a + sizeof(a)。现在我的问题是存储指针变量的大小,还是没有存储指针变量的大小,然后如何计算。在int, float, char等的情况下,它们的大小是在编译器中预定义的,所以int *a是不同的情况。是不是真的只有地址存储在指针变量中没有其他的东西?关于指针变量的元数据被存储在哪里?

+1

重复:http://stackoverflow.com/questions/7194388/using-pointers-in-c – phoxis

它没有被存储。编译器在编译代码时肯定需要跟踪它,但在此之后,它基本上只是硬编码到生成的指令中。

由于您的变量声明int a[5] = ...,编译器知道a类型为int [5](因此,sizeof(a)将返回20)。由于编译器知道a的类型,因此获取a的地址将产生正确类型的指针。这可能有点令人惊讶:&a不会产生int**,而是产生int (*)[5](指向由5个整数组成的数组的指针)。执行

int *ptr=(int*)(&a+1); 

当你的a地址

所以,添加一个(其中,由于方式的C/C++指针算术工作,通过sizeof(a)字节增加了由指针所引用的地址),然后将结果转换为int。因此,在这一点上,ptr指向数组最后一个元素后面(偏移20处)。

然后,您将指针指向int*并使用*(ptr-1),因此您将偏移量为16的int值取消引用 - 这恰好是最后一个数组元素所在的位置。

&一个IS int (*)[5]类型,即,一个&是一个指针数组,不是指针为int。编译器知道(明显)数组的大小,并将其用于指针运算。

指针具有“双重类型”。一方面,它是一个具有自己大小的指针(假设某些系统上的每个指针有4个字节)。另一方面,它是指向具有大小的指针(除了void *之外)。

类型通常不能直接在C中访问。您不能问“变量的类型是什么”。

但大小总是可以通过sizeof访问。因此int *本身可能使用4个字节,但编译器知道它指向一个整数,并且它知道整数的大小。 对于struct xyz *,指针本身可能再次是4个字节,但编译器知道它指向一个结构,并知道结构的大小。重要的是指针的类型超出了“指针”的范围。

所以,如果你定义了struct xyz *ptr,你总是可以通过检查sizeof(*ptr)找出指针指向的大小。即使ptr未初始化,也可以这样做。

您唯一不能做的事情是在ptr定义为void *时检查sizeof(*ptr)

就“元数据”而言,它都是指针的类型。

指针只是一个内存地址,没有元数据。将N添加到类型T *的指针会导致将N * sizeof(T)添加到地址值。编译器在编译期间知道每种类型的大小,不存储任何内容。

  • a+1指向一个第二int,因为它把a作为int*即指针的第一个元素,即的sizeof(int)的被添加到存储器地址
  • &a+1点于“第二INT [5]数组“,即sizeof(int [5])被添加到内存地址
  • ptr-1指向在”第二个数组“的第一个元素之前的int,即a的最后一个元素。