为什么我们不能推广指针声明?

lat*_*ish 4 c c++ pointers

无论指向的数据类型如何,指针的大小都是相同的.那为什么我们需要声明它指向的数据类型?

例如,

int *p;  //p will point to an integer data type.
char *p;  //p will point to a character
Run Code Online (Sandbox Code Playgroud)

那么,为什么我们不能概括这样的指针声明

pointer p;  //where p is an object of pointer class.
Run Code Online (Sandbox Code Playgroud)

Sou*_*osh 13

TL; DR因为,不同的数据类型在内存中占用不同的大小并且具有不同的对齐要求.

详细说明,指针变量包含指向某种类型数据的地址.如果没有关联的类型,就无法取消引用指针并获取.

换句话说,要访问指针指向的数据,必须知道关联的数据类型.

指针本身的大小与它指向的实际数据几乎没有联系.

存在一个指针,void *它被认为是一个通用指针,但是,你不能取消引用它,因为取消引用的结果会尝试产生一个不完整的类型.您需要将其强制转换为完整类型,以便能够取消引用或对void指针应用指针算法.

考虑到背后的原因void *一个普通的指针如下,从引用C11标准,章§6.3.2.3

指针void可以转换为指向任何对象类型的指针.指向任何对象类型的指针可以转换为指向void和返回的指针; 结果应该等于原始指针.

因此,a void *可以用作可以保存任何指针类型的通用容器,但是要对指针进行某些操作(包括数据类型的知识),首先需要将其转换为完整类型.

  • 好的,两个downvotes没有任何评论,我现在真的很感兴趣.任何人? (2认同)

Ton*_*ous 6

指针算术.

说明:

int arr[] = {4, 6, 9, 10};
int* x = arr;

*(x+0) = 4
*(x+1) = 6
Run Code Online (Sandbox Code Playgroud)

编译器知道x + 1实际上是x + sizeof(int)而不是1.

要读取第二个元素,编译器必须每次都跳过sizeof(int).在不知道实际类型的情况下,您无法取消引用它并正确提取数据.

Plus类型的大小不同,编译器需要知道从指向的内存中读取多少字节.char将是1个字节,int将超过1个字节.


Fra*_*eux 6

可以使用泛化指针void*.void*是指向某个地址的指针,没有任何关联的类型信息.但是,如果不将这些指针首先强制转换为显式指针类型,则几乎无法使用这些指针.

请考虑以下示例.它不会编译,因为它不可能推断出ptris所指出的"值" .你甚至不知道该值构成了多少字节.

void print(const void * ptr) {
    std::cout << *ptr; // What's the "value" of ptr?
}
Run Code Online (Sandbox Code Playgroud)