是的,指针是一种数据类型。其中最纯粹的形式(这里主要讲C)是void *。 void * 可用于传递内存地址(这就是指针),但不能取消引用。取消引用指针是为了获取指针指向的内存位置中包含的数据,这意味着您知道从内存中读取的数据类型。类型决定了将读取多少内存,因为void 是“nothing”。 void * 可以设置为指向可以包含任何类型的任何内存块,因此您可以将void * 强制转换为任何其他指针类型(例如int *),然后取消引用它。
我们拥有的每种类型都用于存储特定的数据(值),我们使用char 存储单个字符,int 存储整数,double 存储双精度小数和很快。除了指针之外,这些类型都不用于在内存中存储位置。因此,就像其他类型一样,指针用于存储特定的数据。所有指针之母是void *。
遗憾的是,这个void * 相当受限制:你不能取消引用它,你不能将它用于指针算术(无论如何都不是根据标准)。因此,C 为您提供了一系列派生指针类型,让生活更轻松:char *、int *、double * 等等。
它们实际上是简写形式:(char *) void * my_ptr;
更多尝试尽可能清楚地说明我的观点:
指针有自己的大小,与它们所指向的类型无关:
char a_character = 'a'; //type: a char
char *a_char_ptr = &a_character; //memory address, in this case, the one holding a_charachter
通过查看这两个变量的大小可能最能看出区别:
printf("%zu <> %zu\n", sizeof a_character, sizeof a_char_ptr);
上面的代码会给你类似 "1 8" 或 "1 4" 的东西,这取决于你使用的系统。数字表示大小,以字节为单位。
指针也有自己的printf 格式说明符:%p:
printf("%c is the value stored at %p\n", *a_char_ptr, (void *) a_char_ptr);
要打印实际内存地址(指针的实际值),您需要将指针转换为通用void * 类型。 void 指针是一种通用指针。它是指针,它对它指向的数据不做任何假设。这就是malloc、calloc 和realloc 返回的通用指针,可以设置为指向任何其他类型。那么char * 是什么?它是一种通用指针类型,设置为指向 1 字节大小的内存块 (sizeof(char))。从某种意义上说,类型化指针是派生类型,但可以这样想:char * 是 (char *) void *my_ptr; 的缩写
但实际上,什么是类型?它的要点是,类型是确定如何解释内存中数据的方法。 char 类型的变量代表一个字符。 int 类型的变量代表一个整数。同样适用于指针:char *x 不是char 类型,而是char * 类型(指向字符的指针)。这意味着char *x 本身就是内存中的一个位置,我们可以使用它来读取一个或多个char 值。
我可以咆哮一会儿,但是 TL;TR:
是的,指针是一种数据类型(void * 的最纯粹形式)。纯形式是完全不可用的(因为你不能取消引用它)。不必每次决定使用指针时都强制转换,C 提供了派生指针类型的便利(如char *、int * 等)。但实际上,它们是指针,因此本身就是一种数据类型。