为什么在C中使用指针?

我仍然想知道为什么在C中你不能简单地使用普通变量设置一些东西。 变量本身是指向数据的指针,不是吗? 那么为什么当你可以简单地使用原始变量时,指针指向变量中的数据呢? 是否要访问所述变量中的特定位(或字节,我猜)?

我确信这是合乎逻辑的,但是我从来没有完全掌握这个概念,当阅读代码看到*pointers总是让我失望。

变量本身是指向数据的指针

不它不是。 变量表示一个对象,一个左值左值的概念与指针的概念根本不同。 你好像在混淆两者。

在C中,不可能“重新绑定”左值以使其“指向”内存中的不同位置。 在编译时确定并固定左值与其存储位置之间的绑定。 它并不总是100%特定的(例如,在编译时不知道局部变量的绝对位置),但它足够具体,使其在运行时非用户可调。

指针的整个概念是它的值通常在运行时确定,并且可以在运行时指向不同的存储器位置。

不,变量不是指向数据的指针。 如果用int x, y;声明两个整数int x, y; 那么就没有办法让xy指向同一个东西; 他们是分开的。

无论何时从变量读取或写入,您的计算机都必须以某种方式确定该变量在计算机内存中的确切位置。 您的计算机将查看您编写的代码并使用它来确定变量的位置。 指针可以表示编译代码时未知位置的情况; 确切地址仅在您实际运行代码时才计算。

如果不允许使用指针或数组,那么您编写的每行代码都必须访问编译时已知的特定变量。 您无法编写从调用程序指定的内存中不同位置读取和写入的一般代码。

注意:您还可以使用带有变量索引的数组来访问在编译时位置未知的变量,但是数组通常只是指针的语法糖。 您可以考虑使用指针操作来考虑所有数组操作。 数组不如指针灵活。

另一个警告:正如AnT指出的那样,局部变量的位置通常在堆栈上,因此它们是一种变量,其中位置在编译时是未知的。 但是堆栈用于在可重入函数中存储局部变量的唯一原因是编译器实现了称为堆栈指针和/或帧指针的隐藏指针,函数使用这些指针来找出哪个部分的内存保存其参数和本地变量。 指针非常有用,编译器实际上在你背后使用它们而不告诉你。

指针有用的一个常见位置是编写函数时。 函数“按值”获取它们的参数,这意味着它们获取传入内容的副本,以及函数是否为其中一个不会影响调用者的参数分配新值。 这意味着你不能写这样的“加倍”函数:

 void doubling(int x) { x = x * 2; } 

这是有道理的,否则如果你打电话给这样的加倍,程序会做什么:

 doubling(5); 

指针提供了解决此问题的工具,因为它们允许您编写带有变量地址的函数,例如:

 void doubling2(int *x) { (*x) = (*x) * 2; } 

上面的函数将整数的地址作为参数。 函数体中的一行取消引用该地址两次:在等号的左侧,我们存储到该地址,在右侧,我们从该地址获取整数值,然后将其乘以2最终结果是在该地址找到的值现在加倍。

顺便说一句,当我们想要调用这个新函数时,我们不能传入一个文字值(例如doubling2(5) ),因为它不会编译,因为我们没有正确地给函数一个地址。 给它一个地址的一种方法是这样的:

 int a = 5; doubling2(&a); 

最终结果是我们的变量a将包含10。

另一个原因:C旨在构建操作系统和许多处理硬件的低级代码。 每个硬件都通过寄存器公开其接口,并且几乎在所有体系结构中,寄存器都映射到CPU存储空间,并且它们不必始终位于相同的地址(由于跳线设置,PnP,自动配置等等)上)

因此,OS编写器在编写驱动程序时需要一种处理内存位置的方法,只需要它们不会引用RAM单元。

指针通过允许OS编写者指定他或她想要访问的内存位置来实现此目的。