用 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
,因为 a
和 b
是指针变量,*
运算符将检索 值 b
指向它的内存中的一个单元格,并将其放入 a
指向它的单元格。
对于 *a = &x
,& 运算符找到分配给 x
变量的单元格的 地址 ,并将其放入分配给 x
变量的单元格中指向它。
&x
returns x 的地址。 x 是整数类型,a
是指向整数的指针类型。在这种情况下,(*a = &x),您将 x 的地址分配给类型为 "pointer to integer" 的变量,即 a
。 (*a = *b) 是两个相同类型的整数变量之间的赋值操作。我说整数是因为即使 a
和 b
是 "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 = *b
将 b
指向的 值 赋给 [=12= 指向的值(通过 *b
获得) ].为了看得更清楚,
int tmp = *b;
*a = tmp;
&(*a = &x)
不是有效的表达式,因为您不能将地址存储到 int
中(实际上可以,但那超出了重点)。
我试图更好地理解 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
,因为 a
和 b
是指针变量,*
运算符将检索 值 b
指向它的内存中的一个单元格,并将其放入 a
指向它的单元格。
对于 *a = &x
,& 运算符找到分配给 x
变量的单元格的 地址 ,并将其放入分配给 x
变量的单元格中指向它。
&x
returns x 的地址。 x 是整数类型,a
是指向整数的指针类型。在这种情况下,(*a = &x),您将 x 的地址分配给类型为 "pointer to integer" 的变量,即 a
。 (*a = *b) 是两个相同类型的整数变量之间的赋值操作。我说整数是因为即使 a
和 b
是 "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 = *b
将 b
指向的 值 赋给 [=12= 指向的值(通过 *b
获得) ].为了看得更清楚,
int tmp = *b;
*a = tmp;
&(*a = &x)
不是有效的表达式,因为您不能将地址存储到 int
中(实际上可以,但那超出了重点)。