(初学者)C 中的指针

(beginner) Pointers in C

我被要求编写一个提供

的 C 模块
void swap(struct posn *p, struct posn *q); 

交换ab字段的函数。 示例:

struct posn { int x; int y; };
struct posn a = {1, 2};
struct posn b = {3, 4};
swap(&a, &b);
assert(a.x == 3);
assert(a.y == 4);
assert(b.x == 1);
assert(b.y == 2);

但是*p*q都是指针,所以我写的下面的代码是行不通的:

void swap(struct posn *p, struct posn *q)
{
    int temp1 = *p.x;
    int temp2 = *p.y;
    *p.x = *q.x;
    *p.y = *q.y;
    *q.x = temp1;
    *q.y = temp2;
}

如何交换指针?任何 help/advice 不胜感激!

在表达式*p.x中,.运算符的优先级高于*运算符,因此编译器将其理解为*(p.x),这是无效的,因为p 不是具有字段 x 的结构(它是一个指针)。您可以将其写为 (*p).x,或使用 -> 运算符为您完成此操作:p->x.

* 运算符作用于 . 运算符。所以当你这样做时:

*p.x

你真的在做

*(p.x)

您可以使用:

(*p).x

不过最好写成:

p->x

你快到了。看来您了解指针的工作原理,但您对 operators precedence.

的关注不够

正如您在 the list 中所见,"Structure and union member access" 运算符 (.) 的优先级高于 "Indirection (dereference)" 运算符 (*)。

这就是为什么 *p.x 被评估为 *(p.x) 但您希望它被评估为 (*p).x.

如果你在函数代码中的任何地方添加 *p*q 括号,它将起作用(现在它甚至无法编译)。

因为这种运算符组合(取消引用后跟成员访问)非常常见,语言提供了 -> 运算符,称为 "Structure and union member access through pointer".

代码 p->x(*p).x 等效,但更短且更易读。

您的问题的解决方案非常简单:将 *p.x 替换为 p->x 各处:

void swap(struct posn *p, struct posn *q)
{
    int temp1 = p->x;
    int temp2 = p->y;
    p->x = q->x;
    p->y = q->y;
    q->x = temp1;
    q->y = temp2;
}