我试图更好地理解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;
}
我将以下内容混为一谈,看看它是否能帮助我更好地了解正在发生的事情,主要是因为需要使用&amp;与*(取消引用)。基本上,声明指向int类型(int * a)的指针与使用星号指向“取消引用”(* 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
)之间的区别是什么。
答案 0 :(得分:6)
你混淆了声明和作业。
*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;
}
最后,当您在同一语句中声明和初始化指针 时,您将指针指定为地址你想要指出的是什么。如果要更改对象指向的值,则使用*
取消引用。另一方面,如果您想要更改指向的,则不取消引用它。
答案 1 :(得分:4)
&x
返回x的地址。 x的类型为整数,a
的类型为整数的指针。在这种情况下,(* a =&amp; x),您将x的地址分配给“指向整数的指针”类型的变量,即a
。 (* a = * b)是两个相同类型的变量之间的赋值操作,它是整数。我说整数是因为即使a
和b
是“指向整数的指针”,在该操作中它们被解除引用,因此读取这些指向的整数值。
我认为你的困惑是因为(* a =&amp; x)在指针初始化期间才有意义。
答案 2 :(得分:1)
如果您设置*a = *b
,a
和b
是指针变量,*
运算符将检索内存中单元格的值 b
指向它并将其放到a
指向它的单元格中。
*a = &x
,&amp;运算符找到分配给x
变量的单元格的地址,并将其放入指向它的单元格中。
答案 3 :(得分:-1)
简而言之,我的问题是,它们之间是否存在功能差异 这两个项目正在做什么?
不,功能效果完全相同。在
int *a = &x;
int *b = &y;
swap(a, b);
// swap(&a, &b)
a
的类型与&a
相同,即int*
(指向int
的指针)。唯一的区别是你使用其他变量来存储它,这在逻辑上并不是真正需要的,但是拥有它是绝对正常的,特别是如果它可以帮助你理解语法。
取消引用(* a = * b)与使用&amp; (* a =&amp; x)。
*a = *b
将b
指向的值(由*b
获得)指定为a
指向的值。为了更清楚地看到它,
int tmp = *b;
*a = tmp;
&(*a = &x)
不是有效的表达式,因为您无法将地址存储到int
中(实际上您可以,但超出了这一点)。