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

C 指针变量的大小存储在哪里?,c,arrays,pointers,C,Arrays,Pointers,在语句*ptr=(int*)(&a+1)中,1未添加到&a中。实际上,它类似于&a+sizeof(a)。现在我的问题是指针变量的大小存储在哪里,或者若并没有存储,那个么它是如何计算的。在int、float、char等的情况下,它们的大小是在编译器中预定义的,因此int*a是不同的情况。指针变量中只存储了地址,而没有存储其他内容,这是真的吗?。指针变量的元数据存储在哪里 它不会被存储。编译器在编译代码时当然需要跟踪这一点,但在此之后,它基本上只是硬编码到生成的指令中。由于变量声明inta[5]=…

在语句
*ptr=(int*)(&a+1)中,
1未添加到
&a
中。实际上,它类似于
&a+sizeof(a)
。现在我的问题是指针变量的大小存储在哪里,或者若并没有存储,那个么它是如何计算的。在
int、float、char
等的情况下,它们的大小是在编译器中预定义的,因此int
*a
是不同的情况。指针变量中只存储了地址,而没有存储其他内容,这是真的吗?。指针变量的元数据存储在哪里

它不会被存储。编译器在编译代码时当然需要跟踪这一点,但在此之后,它基本上只是硬编码到生成的指令中。

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

所以在执行的时候

2 5
您获取
a
的地址,添加一个(由于C/C++指针算术的工作方式,它将指针引用的地址增加
sizeof(a)
字节),然后将结果强制转换为int。因此,此时,
ptr
指向数组最后一个元素的后面(偏移量20)

然后将指针强制转换为
int*
,并使用
*(ptr-1)
,这样就可以取消对偏移量16处的int值的引用,偏移量16正好是最后一个数组元素所在的位置。

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

指针具有“双精度类型”。一方面,它是一个具有自己大小的指针(在某些系统中,每个指针有4个字节)。另一方面,它是一个指针,指向具有大小的对象(除了
void*

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

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

因此,如果您定义
struct xyz*ptr
,您总是可以通过检查
sizeof(*ptr)
,找到指针指向的对象的大小。即使未初始化
ptr
,也可以这样做

当定义了
ptr
时,您唯一不能做的就是检查
sizeof(*ptr)


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

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

  • a+1
    指向a中的第二个
    int
    ,因为它将
    a
    视为
    int*
    ,即指向第一个元素的指针,即sizeof(int)添加到内存地址
  • &a+1
    指向“第二个int[5]数组”,即sizeof(int[5])被添加到内存地址
  • ptr-1
    指向“第二个数组”的第一个元素(即a的最后一个元素)正前方的
    int
重复:
2 5
int *ptr=(int*)(&a+1);