原文: https://www.programiz.com/c-programming/c-pointers

在本教程中,您将学习指针。 什么是指针,如何使用它们以及在示例的帮助下使用它们时可能遇到的常见错误。

指针是 C 和 C++ 编程的强大功能。 在学习指针之前,让我们学习一下 C 编程中的地址。


C 地址

如果程序中有变量var,则&var将在内存中提供其地址。

使用scanf()函数时,我们已多次使用地址。

  1. scanf("%d", &var);

在此,用户输入的值存储在var变量的地址中。 让我们举一个可行的例子。

  1. #include <stdio.h>
  2. int main()
  3. {
  4. int var = 5;
  5. printf("var: %d\n", var);
  6. // Notice the use of & before var
  7. printf("address of var: %p", &var);
  8. return 0;
  9. }

输出

  1. var: 5
  2. address of var: 2686778

注意:运行上面的代码时,您可能会获得其他地址。


C 指针

指针(指针变量)是用于存储地址而非值的特殊变量。

指针语法

这是我们如何声明指针的方法。

  1. int* p;

在这里,我们声明了int类型的指针p

您也可以通过以下方式声明指针。

  1. int *p1;
  2. int * p2;

让我们再举一个声明指针的例子。

  1. int* p1, p2;

在这里,我们声明了一个指针p1和一个正常变量p2


给指针分配地址

让我们举个例子。

  1. int* pc, c;
  2. c = 5;
  3. pc = &c;

在此,将c变量分配为 5。 并且,将c的地址分配给pc指针。


获取指针所指的值

要获取指针所指向的值,我们使用*运算符。 例如:

  1. int* pc, c;
  2. c = 5;
  3. pc = &c;
  4. printf("%d", *pc); // Output: 5

此处,c的地址分配给pc指针。 为了获得存储在该地址中的值,我们使用了* pc

注意:在上面的示例中,pc是指针,而不是*pc。 您不能也不应做类似*pc = &c的操作;

顺便说一下,*被称为解除引用运算符(使用指针时)。 它对指针进行操作并给出存储在该指针中的值。


改变指针指向的值

让我们举个例子。

  1. int* pc, c;
  2. c = 5;
  3. pc = &c;
  4. c = 1;
  5. printf("%d", c); // Output: 1
  6. printf("%d", *pc); // Ouptut: 1

我们已经将c的地址分配给pc指针。

然后,我们将c的值更改为 1。由于pcc的地址相同,所以*pc给出 1。

让我们再举一个例子。

  1. int* pc, c;
  2. c = 5;
  3. pc = &c;
  4. *pc = 1;
  5. printf("%d", *pc); // Ouptut: 1
  6. printf("%d", c); // Output: 1

We have assigned the address of c to the pc pointer.

然后,我们使用*pc = 1;*pc更改为 1。 由于pcc的地址相同,因此c等于 1。

让我们再举一个例子。

  1. int* pc, c, d;
  2. c = 5;
  3. d = -15;
  4. pc = &c; printf("%d", *pc); // Output: 5
  5. pc = &d; printf("%d", *pc); // Ouptut: -15

最初,使用pc = &c;c的地址分配给pc指针。 由于c为 5,因此*pc给我们 5。

然后,使用pc = &d;d的地址分配给pc指针。 由于d为 -15,因此*pc给我们 -15。


示例:指针的工作原理

让我们举一个可行的例子。

  1. #include <stdio.h>
  2. int main()
  3. {
  4. int* pc, c;
  5. c = 22;
  6. printf("Address of c: %p\n", &c);
  7. printf("Value of c: %d\n\n", c); // 22
  8. pc = &c;
  9. printf("Address of pointer pc: %p\n", pc);
  10. printf("Content of pointer pc: %d\n\n", *pc); // 22
  11. c = 11;
  12. printf("Address of pointer pc: %p\n", pc);
  13. printf("Content of pointer pc: %d\n\n", *pc); // 11
  14. *pc = 2;
  15. printf("Address of c: %p\n", &c);
  16. printf("Value of c: %d\n\n", c); // 2
  17. return 0;
  18. }

输出

  1. Address of c: 2686784
  2. Value of c: 22
  3. Address of pointer pc: 2686784
  4. Content of pointer pc: 22
  5. Address of pointer pc: 2686784
  6. Content of pointer pc: 11
  7. Address of c: 2686784
  8. Value of c: 2

程序的说明

  1. int* pc, c;
    C 指针 - 图1
    此处,创建了类型均为int的指针pc和常规变量c
    由于pcc最初并未初始化,因此指针pc指向无地址或随机地址。 并且,变量c具有地址,但包含随机垃圾值。

  2. c = 22;
    C 指针 - 图2
    这将 22 分配给变量c。 即,将 22 存储在变量c的存储单元中。

  3. pc = &c;
    C 指针 - 图3
    这将变量c的地址分配给指针pc

  4. c = 11;
    C 指针 - 图4
    这将 11 分配给变量c

  5. *pc = 2;
    C 指针 - 图5
    将指针pc指向的存储位置的值更改为 2。


使用指针时的常见错误

假设您希望指针pc指向c的地址。 然后,

  1. int c, *pc;
  2. // pc is address but c is not
  3. pc = c; // Error
  4. // &c is address but *pc is not
  5. *pc = &c; // Error
  6. // both &c and pc are addresses
  7. pc = &c;
  8. // both c and *pc values
  9. *pc = c;

这是指针语法初学者经常会感到困惑的示例。

  1. #include <stdio.h>
  2. int main() {
  3. int c = 5;
  4. int *p = &c;
  5. printf("%d", *p); // 5
  6. return 0;
  7. }

使用int *p = &c;时为什么没有出现错误?

这是因为

  1. int *p = &c;

相当于

  1. int *p:
  2. p = &c;

在这两种情况下,我们都将创建一个指针p(不是*p)并为其分配&c

为了避免这种混乱,我们可以使用如下语句:

  1. int* p = &c;

现在您知道了什么是指针,您将在下一个教程中学习指针与数组的关系。