关于C指针:C指针 – 交换

C Pointers - swap

我在玩C…与接收指向值的指针和交换值的常规交换不同,我尝试编写接收指向值的指针、检索指针的指针和交换指向值的指针的交换。

这是密码……

交换函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
void swap(void *left, void *right)
{
puts("
swap function:

"
);

printf("&left :  %i   -   left:  %i   -   *left(should be a):  %i
"
,
            &left, left, *((int *)left));
printf("&right : %i   -   right: %i   -   *right(should be b): %i

"
,
            &right, right, *((int *)right));

void *PNT_left =  (void *) &left;
void *PNT_right = (void *) &right;

puts("Before swap:");
printf("PNT_left:  %i   -   left: %i
"
, (int *)PNT_left, *((int *)PNT_left));
printf("PNT_right: %i   -   right: %i

"
, (int *)PNT_right, *((int *)PNT_right));

/* swap pointers of pointers*/
void *tmpPNT = PNT_left;
PNT_left = PNT_right;
PNT_right = tmpPNT;

puts("Pointer of pointer swapped:");
printf("PNT_left:  %i   -   left: %i
"
, (int *)PNT_left, *((int *)PNT_left));
printf("PNT_right: %i   -   right: %i

"
, (int *)PNT_right, *((int *)PNT_right));

/* swap pointers*/
tmpPNT = (void *)right;
*((int *)PNT_left) = (int *)left;
*((int *)PNT_right) = (int *)tmpPNT;

puts("Pointer swapped:");
printf("PNT_left:  %i   -   left: %i
"
, (int *)PNT_left, *((int *)PNT_left));
printf("PNT_right: %i   -   right: %i

"
, (int *)PNT_right, *((int *)PNT_right));

puts("Info:");
printf("&left :  %i   -   left:  %i   -   *left:  %i
"
,
    &left, left, *((int *)left));
printf("&right : %i   -   right: %i   -   *right: %i

"
,
    &right, right, *((int *)right));

puts("End Swap function.


"
);
return;
}

主营:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
int main()
{
    int a = 1, b = 2;

    puts("Before - Info:");
    printf(" a: %i   -    b: %i
"
, a, b);
    printf("*a: %i   -   *b: %i

"
, &a, &b);

    swap(&a, &b);

    puts("After - Info:");
    printf("*a: %i   -   *b: %i
"
, &a, &b);
    printf(" a: %i   -    b: %i
"
, a, b);
    return 0;
}

输出:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
Before - Info:
 a: 1   -    b: 2
*a: -346930776   -   *b: -346930772


Swap function:

&left :  -346930760   -   left:  -346930776   -   *left(should be a):  1
&right : -346930752   -   right: -346930772   -   *right(should be b): 2

Before swap:
PNT_left:  -346930760   -   left: -346930776
PNT_right: -346930752   -   right: -346930772

Pointer of pointer swapped:
PNT_left:  -346930752   -   left: -346930772
PNT_right: -346930760   -   right: -346930776

Pointer swapped:
PNT_left:  -346930752   -   left: -346930776
PNT_right: -346930760   -   right: -346930772

Info:
&left :  -346930760   -   left:  -346930772   -   *left:  2
&right : -346930752   -   right: -346930776   -   *right: 1

End Swap function.


*a: -346930776   -   *b: -346930772
 a: 1   -    b: 2

为什么A和B没有交换?我也尝试过它,所以它与传递引用或值无关。

如果我尝试打印输出*((int*)((int*)pnt_left)),程序会在打印输出*((int)left)工作时达到分段错误,因为在开始时*((int*)pnt_left))=left?

谢谢大家!


1
2
void *PNT_left =  (void *) &left;
void *PNT_right = (void *) &right;

将局部变量的地址作为指针通过C中的值传递。如果要更改函数中的指针并使此更改在函数外部可见,则必须传递指针的地址。

您可以在这里找到您的代码。

你应该在第33行加上这个

1
2
3
4
/* swap values*/
int tmp = *((int*)(*left));
*((int *)(*left)) = *((int *)(*right));
*((int *)(*right)) = tmp;

你也应该交换数据。


如果要更改指针指向函数内部的位置,必须将指针指向函数。否则,指针将被复制,而您只更改函数内的指针。

这样想:使用函数void myfunc(int a)a将被复制,您不能从内部更改函数外部的值。如果使用指针myfunc(int *a),则可以在函数外部更改值。因此,如果要在外部更改指针的值,则必须传递指针。

举例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <stdio.h>

void swap_ptr(int **a, int **b) {
    void *buffer = *a;
    *a = *b;
    *b = buffer;
}

int main(int argc, char *argv[]) {
    int a = 1;
    int b = 2;

    int *a_ptr = &a;
    int *b_ptr = &b;

    printf("%p %p
"
,  a_ptr,  b_ptr);
    printf("%i %i
"
, *a_ptr, *b_ptr);

    swap_ptr(&a_ptr, &b_ptr);
    printf("-- swap --
"
);

    printf("%p %p
"
,  a_ptr,  b_ptr);
    printf("%i %i
"
, *a_ptr, *b_ptr);
}

输出:

1
2
3
4
5
0x7fff5c663b6c 0x7fff5c663b68
1 2
-- swap --
0x7fff5c663b68 0x7fff5c663b6c
2 1