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

时间:2010-02-04 14:36:04

标签: c pointers

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

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

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

10 个答案:

答案 0 :(得分:20)

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

答案 1 :(得分:14)

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

*a = *b + *c;    // Should this add char? int? float?
s_ptr->x = 0;    // How does the compiler know anything about the structure s_ptr points to?
a[5] = 0;        // How far is a[5] from a[0]?

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

答案 2 :(得分:8)

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

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

或者给出

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

对结构对的void指针有多大用处?您可能想要访问其first成员,如果您没有指向结构对的指针,那么这将是很多工作。

答案 3 :(得分:4)

死简单:

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

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

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

答案 4 :(得分:3)

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

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

但这是一个很好的简化。

答案 5 :(得分:2)

实际上,它是“指向无效的指针”,需要解释。

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

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

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

答案 6 :(得分:2)

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

答案 7 :(得分:0)

两个字:类型安全

维基百科上的type safety (or lack thereof) in C上有一点点消息,可能会为你提供一些启示。

答案 8 :(得分:0)

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

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

#include <stdio.h>

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字节)

答案 9 :(得分:0)

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

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