无论指向的数据类型如何,指针的大小都是相同的.那为什么我们需要声明它指向的数据类型?
例如,
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 *可以用作可以保存任何指针类型的通用容器,但是要对指针进行某些操作(包括数据类型的知识),首先需要将其转换为完整类型.
指针算术.
说明:
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个字节.
你可以使用泛化指针void*.void*是指向某个地址的指针,没有任何关联的类型信息.但是,如果不将这些指针首先强制转换为显式指针类型,则几乎无法使用这些指针.
请考虑以下示例.它不会编译,因为它不可能推断出ptris所指出的"值" .你甚至不知道该值构成了多少字节.
void print(const void * ptr) {
std::cout << *ptr; // What's the "value" of ptr?
}
Run Code Online (Sandbox Code Playgroud)