用 C 中的交换程序理解指针

Understanding pointers with a swap program in C

我试图更好地理解 C 中的指针和引用,我的课程提供了以下程序作为示例。

#include <stdio.h>

void swap(int* a, int* b);

int main(void)
{
    int x = 1;
    int y = 2;

    swap(&x, &y);
    printf("x is %i\n", x);
    printf("y is %i\n", y);
}

void swap(int* a, int* b)
{
    int tmp = *a;
    *a = *b;
    *b = tmp;
}

我将以下内容拼凑在一起,看看它是否能帮助我更好地理解正在发生的事情,主要是关于使用 & 与 *(取消引用)的需要。基本上,声明指向 int 类型的指针 (int* a) 与使用星号指向 "dereference" (*a = *b) 的语法让我很困惑,我希望有人能启发我。这是我认为有助于澄清的上述内容的另一个版本,但实际上没有帮助:

#include <stdio.h>

void swap(int* a, int* b);

int main(void)
{
    int x = 1;
    int y = 2;
    int *a = &x;
    int *b = &y;

    swap(a, b);
    printf("x is %i\n", x);
    printf("y is %i\n", y);
}

void swap(int* a, int* b)
{
    int tmp = *a;
    *a = *b;
    *b = tmp;
}

简而言之,我的问题是,这两个程序的功能有区别吗?取消引用 (*a = *b) 与使用 & 运算符 (*a = &x) 之间有什么区别。

你混淆了声明和赋值。

*a = *b被称为赋值。请注意它包含类型名称。

另一方面,

int *a = &x 称为 声明 。请注意,您使用 x 的地址 初始化 指针 。您不是取消引用指针,而是声明它是指向 int 的指针。

看看这个:

int main() {
  int a = 5;
  int b = 2;
  int *c = &a; // c when dereferenced equals 5; **Declaration**
  int *d = &b; // d when dereferenced equals 2; **Declaration**
  int tmp = *c; // tmp equals 5
  *c = *d; // c when dereferenced now equals 2 **Assignment**
  *d = tmp; // d when dereferenced now equals 5 **Assignment**
  return 0;
}

最后,当您在同一语句声明初始化一个指针时,您将指针分配给您想要指向的内容的地址。当你想更改对象指向的时,你取消引用它使用*.另一方面,如果您想更改 它指向的内容,您可以 not 取消引用它。

如果您设置 *a = *b,因为 ab 是指针变量,* 运算符将检索 b 指向它的内存中的一个单元格,并将其放入 a 指向它的单元格。

对于 *a = &x,& 运算符找到分配给 x 变量的单元格的 地址 ,并将其放入分配给 x 变量的单元格中指向它。

&xreturns x 的地址。 x 是整数类型,a 是指向整数的指针类型。在这种情况下,(*a = &x),您将 x 的地址分配给类型为 "pointer to integer" 的变量,即 a。 (*a = *b) 是两个相同类型的整数变量之间的赋值操作。我说整数是因为即使 ab 是 "pointers to integers",在该操作中它们被取消引用,因此读取它们指向的整数值。

我认为您的困惑是因为 (*a = &x) 仅在指针初始化期间才有意义。

In short, my question is, is there a functional difference between what these two programs are doing?

不是,功能效果完全一样。在

int *a = &x;
int *b = &y;

swap(a, b); 
// swap(&a, &b) 

a的类型与&a相同,即int*(指向int的指针)。唯一的区别是您使用其他变量来存储它,这在逻辑上并不是真正需要的,但拥有它绝对没问题,特别是如果它可以帮助您理解语法。

What is the difference between a dereference (*a = *b) versus using & (*a = &x).

*a = *bb 指向的 赋给 [=12= 指向的值(通过 *b 获得) ].为了看得更清楚,

int tmp = *b;
*a = tmp;

&(*a = &x) 不是有效的表达式,因为您不能将地址存储到 int 中(实际上可以,但那超出了重点)。