为什么我们有指针而不是void

我知道我们有不同的指针,如intfloatcharvoid指针是唯一可以容纳所有其他指针的指针。

其他指针是否存在只是为了灵活地进行指针运算?

C语言中是否存在除void之外的指针还有其他原因吗?

类型安全。 定义指针类型有助于编译器在尝试通过指针使用错误类型的数据时发现错误。 这就是C首先出现类型的原因。

编译器需要知道指向的类型,否则各种代码将无法工作。 考虑以下:

 * a = * b + * c;  //这应该添加char吗? 诠释? 浮动?
 s_ptr-> x = 0;  //编译器如何知道有关s_ptr指向的结构的任何信息?
 a [5] = 0;  //从[0]到[5]有多远?

没有指针类型就像没有任何类型的东西。 编译器将完全丢失。 简而言之,C和C ++都是强类型的,并且由于相当明显的原因而转移到指针。

 int o = 12; void *i = &o; 

如果只有void指针而没有int *,你将如何访问i指向的int。 您可能知道在您的平台上,int是4个字节,因此您可以从void *指向的任何内容开始记忆4个字节到临时int,然后使用它。 但那不是很方便。

或给出一个

 struct Pair { char *first; char *second; }; 

一个指向struct Pair的void指针有多大用处? 你可能想要访问它的first成员,如果你没有指向结构对的指针,这将是很多工作。

死简单:

 void* p; *p; // compile error! 

或者说出来; 无法取消引用void指针。

也许你应该重新命名这个问题为什么我们有指针,或者更确切地说,不要只是在SO上搜索那个问题。

当您使用指向float或int的指针时(例如)编译器知道它应从内存中获取多少字节(例如,int *的sizeof(int))。

使用void您必须每次都要告诉编译器需要多少字节(例如,通过写(int *)some_void_ptr)。

但这是一个很大的简化。

实际上,它是“指向无效的指针”,这将被解释。

在一般的编程语言中,特别是在C语言中,我们喜欢类型。 类型是基本的安全网,它检查我们是否正在做一些愚蠢的事情,其中​​“愚蠢”的意思是“解释一堆比特他们不是”。 有可能没有类型编程,有些语言完全没有任何类型(例如汇编或Forth),但这不适合胆小的人,一般来说,程序员的生产力似乎通过使用类型大大增强。

因此,当我们有一个指针时,我们希望计算机知道指针末尾可能找到的内容。 我们想要一个“指向int的指针”,以便计算机检查当我们查看位于指针末尾的位时,我们将它们视为“int”而不是其他东西。

“指向void的指针”是无类型指针,当C的类型系统无法捕获我们正在做的事情时,我们使用它。 这是C无法跟踪我们正在生成的代码的复杂性的一个症状(或者程序员可能不足以表达他在C类型系统的约束内所做的事情)。 因此,虽然“void *”在某些情况下很方便,但应该将其视为例外,并努力避免它。

C中指针的类型告诉编译器,如果您尝试取消引用它,则要读取的内存块大小是多少。 换句话说,当取消引用int指针时,编译器知道必须在地址之后读取4个字节。 这就是为什么禁止取消引用void指针而不将其强制转换为类型指针的原因 – 在这种情况下,编译器不知道在地址之后要读取多少字节。

当您遍历指针指向的内存块时,必须知道内存包含的数据类型的大小。 假设你有两个指针,一个char charptr和一个int intptr,都指向字节X处的内存.charptr + 1将指向字节X + 1,而intptr + 1将指向字节X + 4。

一段快速而肮脏的编写错误的代码来说明:

 #include  int main() { char * cptr = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; short * sptr = (short*)cptr; int * iptr = (int*)cptr; long long * lptr = (long long*)cptr; printf ("CHAR: %d, +1: %d\n",cptr,cptr+1); printf ("SHORT: %d, +1: %d\n",sptr,sptr+1); printf ("INT: %d, +1: %d\n",iptr,iptr+1); printf ("LONG LONG: %d, +1: %d\n",lptr,lptr+1); } 

这应该:

  • 生成关于铸造不同尺寸指针(类型安全)的警告,
  • 在第一列中输出相同的数字(所有指针指向内存中的相同地址),但第二列中的数字不同(这是基地址+指针类型的大小:1,2,4和8字节)。

两个词:类型安全

维基百科上的C类型安全性(或缺乏安全性)可能会有一些消息,可能会为您带来一些启示。

C语言中是否存在除void之外的指针还有其他原因吗?

它们是一种自由处理内存块的绝佳方式。 🙂