为什么必须指定指针类型?

时间:2017-06-03 14:49:02

标签: c++

为什么必须为指针设置类型?它们不仅仅是地址和所有地址的占位符吗?因此,无论指定的类型占用相同大小的内存,都不会获得所有指针?

3 个答案:

答案 0 :(得分:11)

您不必为指针指定类型。您可以在任何地方使用./,这会强制您在每次从指针指向的地址读取内容时插入显式类型转换,或者向该地址写入内容,或者只是递增/递减或以其他方式操纵指针的值。

但人们很久以前就决定他们厌倦了这种编程方式,并且首选的类型指针

  • 不需要演员
  • 不需要总是必须知道指向类型的大小(这是一个在必须考虑适当的内存对齐时变得更加复杂的问题)
  • 防止您意外访问错误的数据类型或使用错误的字节数推进指针。

是的,确实,所有数据指针,无论其类型如何,都占用相同数量的内存,通常在32位系统上为4个字节,在64位系统上为8个字节。数据指针的类型与指针占用的内存量无关,这是因为没有类型信息与指针一起存储;指针类型仅对人类和编译器有用,而不对机器有用。

答案 1 :(得分:1)

不同类型会占用不同的内存量。因此,当推进指针(例如在数组中)时,我们需要考虑类型的大小。 例如,因为char只占用一个字节,所以转到下一个元素意味着将0x01添加到该地址。但是因为int占用4个字节(在许多架构上),所以到达下一个元素需要将0x04添加到存储在指针中的地址。 现在,我们可以有一个单一的指针类型,它只是描述一个没有类型信息的地址(事实上,这就是void *的用途),但是每当我们想要增加或减少它时,我们需要给出类型的大小也是如此。

这是一些真实的C代码,它们展示了您将要经历的痛苦:

#include <stdlib.h>
typedef void* pointer;
int main(void) {
    pointer numbers = calloc(10, sizeof(int));
    int i;
    for (i = 0; i < 10; i++)
        *(int*)(numbers + i * sizeof(int)) = i;
        /* this could have been simply "numbers[i] = i;" */
    /* ... */
    return 0;
}

这里要注意三件重要的事情:

  • 我们必须每次将索引乘以sizeof(int);加入 我根本不会这样做:第一次迭代会正确访问 第一个4字节整数,但第二次迭代会寻找 整数,以第一个整数的第二个字节开头 第三个将从第一个整数的第三个字节开始,等等 上。这是不太可能的![/ li>
  • 编译器需要知道它可以存储多少信息 分配给它指向的地址时的指针。例如,如果 您尝试在编译器char中存储大于2 ^ 8的数字 应该知道截断数字而不是覆盖下几个 内存的字节,可能会扩展到下一页(导致 分段错误)或更糟糕的是,用于存储您的其他数据 程序,导致一个微妙的错误。
  • 说到宽度,我们在上面的程序中知道数字商店 整理 - 如果我们没有?例如,如果我们试图存储一个 地址中的int指向较大数据类型的数组(在某些数据类型上) 架构),好像很长?然后我们的通用函数将结束 必须比较两种类型的宽度,可能使用 两个中的最小值,然后如果存储的类型小于 它的容器你开始不得不担心字节序确保 您将存储的值与正确的结尾对齐 容器

答案 2 :(得分:0)

如果你想用指针评估指向元素的值,那么你必须在声明指针上指定指向元素的类型。因为编译器不知道指针所指的确切字节数。机器必须计算特定的有界内存来评估值。