理解C中交换程序的指针

时间:2015-08-11 18:27:36

标签: c pointers dereference address-operator

我试图更好地理解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)之间的区别是什么。

4 个答案:

答案 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)是两个相同类型的变量之间的赋值操作,它是整数。我说整数是因为即使ab是“指向整数的指针”,在该操作中它们被解除引用,因此读取这些指向的整数值。

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

答案 2 :(得分:1)

如果您设置*a = *bab是指针变量,*运算符将检索内存中单元格的 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 = *bb指向的(由*b获得)指定为a指向的值。为了更清楚地看到它,

int tmp = *b;
*a = tmp;

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