我已经将我的问题简化为这个小C程序。请注意,我正在自学C。我真的很难用指针!
#include <stdio.h>
#include <stdlib.h>
typedef struct Elmt_ {
int *i;
struct Elmt_ *next;
} E;
void swap_1(E *x, E *y) {
int *temp = NULL;
temp = x->i;
x->i = y->i;
y->i = temp;
}
void swap_2(E *x, E *y) {
int *temp=NULL;
temp = malloc(sizeof(int));
*temp = *(x->i);
*(x->i) = *(y->i);
*(y->i) = *temp;
}
int main() {
E *p, *q, *r, *s;
int a, b;
a = 8;
b = 50;
p = malloc(sizeof(E));
q = malloc(sizeof(E));
p->i = &a;
p->next = NULL;
q->i = &b;
q->next = NULL;
printf("Initially, *(p->i)=%d *(q->i)=%dn", *(p->i), *(q->i));
swap_1(p,q);
printf("After swap_1, *(p->i)=%d *(q->i)=%dn", *(p->i), *(q->i));
r = malloc(sizeof(E));
s = malloc(sizeof(E));
r->i = &a;
s->i = &b;
printf("Initially, *(r->i)=%d *(s->i)=%dn", *(r->i), *(s->i));
swap_2(r,s);
printf("After swap_2, *(r->i)=%d *(s->i)=%dn", *(r->i), *(s->i));
return 0;
}
**问题:**在上面的程序中,swap_1
或swap_2
是交换i
指向的整数值的正确方法吗?
我发现这两个函数似乎都正确地交换了作为参数给出的值。
$ ./a.out
Initially, *(p->i)=8 *(q->i)=50
After swap_1, *(p->i)=50 *(q->i)=8
Initially, *(r->i)=8 *(s->i)=50
After swap_2, *(r->i)=50 *(s->i)=8
函数swap_1
交换指针值,而不是指针值。
函数swap_2
交换指向的值,但会产生内存泄漏。
为了干净地交换指针值,您可以简单地执行以下操作:
void swap_3(E *x, E *y) {
int temp;
temp = *(x->i);
*(x->i) = *(y->i);
*(y->i) = temp;
}
让我们取swap_1
函数:
void swap_1(E *x, E *y) {
int *temp = NULL;
temp = x->i;
x->i = y->i;
y->i = temp;
}
绘制每一步,看看会发生什么。
让我们从开始
int *temp = NULL;
看看你所有的指针,看看它们指向哪里,然后它会看起来像这样:
+------+ | temp | --> NULL +------+ +---+ +---+ +-------------+ | x | --> | i | --> | a from main | +---+ +---+ +-------------+ +---+ +---+ +-------------+ | y | --> | i | --> | b from main | +---+ +---+ +-------------+
现在让我们做第一项任务:
temp = x->i;
看看它是如何改变事情的:
+------+ | temp | ---------- +------+ | +-------------+ >--> | a from main | +---+ +---+ | +-------------+ | x | --> | i | --/ +---+ +---+ +---+ +---+ +-------------+ | y | --> | i | --> | b from main | +---+ +---+ +-------------+
正如您所看到的,现在有两个指针,它们都指向同一位置(
main
函数中的a
变量(。现在让我们做第二项任务:
x->i = y->i;
这将改变这样的事情:
+------+ +-------------+ | temp | --> | a from main | +------+ +-------------+ +---+ +---+ | x | --> | i | -- +---+ +---+ | +-------------+ >--> | b from main | +---+ +---+ | +-------------+ | y | --> | i | --/ +---+ +---+
同样,有两个指针都指向同一位置(
x->i
和y->i
都指向main
函数中的变量b
(。最后是最后一项任务:
y->i = temp;
完成此分配后,指针将如下所示:
+---+ +---+ +-------------+ | x | --> | i | --> | b from main | +---+ +---+ +-------------+ +------+ | temp | ---------- +------+ | +-------------+ >--> | a from main | +---+ +---+ | +-------------+ | y | --> | i | --/ +---+ +---+
由此可见,swap_1
函数不会交换main
函数中a
和b
变量的值。相反,它交换指针x->i
和y->i
。CCD_ 19和CCD_。
要交换a
和b
的实际值,您需要取消引用指针,并为temp
:使用纯非指针类型
void swap_1(E *x, E *y)
{
int temp = *x->i; // Copy the value from where x->i points
*x->i = *y->i; // Copy the value
*y->i = temp; // Copy the value again
}
如果你将来在指针方面有问题,使用铅笔和纸来绘制和重新绘制变量,类似于上面的指针通常有助于可视化实际发生的事情。我建议你自己试试。