我被要求编写一个提供
的C模块void swap(struct posn *p, struct posn *q);
用于交换a
和b
字段的功能。
例如:
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;
}
如何交换指针?任何帮助/建议表示赞赏!
答案 0 :(得分:7)
在表达式*p.x
中,.
运算符的优先级高于*
运算符,因此编译器将其理解为*(p.x)
,这是无效的,因为{{1} }}不是带有字段p
的结构(它是指针)。您可以将其写为x
,也可以使用为您执行此操作的(*p).x
运算符:->
。
答案 1 :(得分:6)
你快到了。看来你明白了指针是如何工作的,但是你没有在operators precedence得到足够的重视。
正如您在the list中所看到的,“结构和联合成员访问”运算符(.
)的优先级高于“间接(取消引用)”运算符(*
)。
这就是*p.x
被评估为*(p.x)
的原因,但您希望将其评估为(*p).x
。
如果在函数代码中的*p
和*q
附近添加括号,它将起作用(现在它甚至不能编译)。
因为这些运算符组合(取消引用后跟成员访问)非常常见,所以该语言提供了->
运算符,称为“通过指针访问结构和联合成员”。
代码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;
}
答案 2 :(得分:2)
*
运算符正在.
运算符上运行。所以当你这样做时:
*p.x
你真的在做
*(p.x)
您可以使用:
(*p).x
但这更好地写成:
p->x