【问题标题】:C Pointers - swapC 指针 - 交换
【发布时间】:2016-02-28 12:05:36
【问题描述】:

我正在玩 C 中的指针... 而不是接收指向值的指针和交换值的常规交换,我正在尝试编写一个交换来接收指向值的指针,检索指针的指针并交换指向值的指针。

这是代码...


交换功能:

void swap(void *left, void *right)
{
puts("\nswap function:\n\n");

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

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

puts("Before swap:");
printf("PNT_left:  %i   -   left: %i\n", (int *)PNT_left, *((int *)PNT_left));
printf("PNT_right: %i   -   right: %i\n\n", (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\n", (int *)PNT_left, *((int *)PNT_left));
printf("PNT_right: %i   -   right: %i\n\n", (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\n", (int *)PNT_left, *((int *)PNT_left));
printf("PNT_right: %i   -   right: %i\n\n", (int *)PNT_right, *((int *)PNT_right));

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

puts("End Swap function.\n\n\n");
return;
}


主要:

int main()
{
    int a = 1, b = 2;

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

    swap(&a, &b);

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


输出:

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 没有交换?我也在main中尝试过,所以它与通过ref或value传递无关。


以及为什么如果我尝试打印出 *((int *) *((int *)PNT_left)) 程序会在打印出 *((int) left) 工作时达到 SEGMENTATION FAULT,因为一开始 *((int *) PNT_left)) = 左?


谢谢大家!

【问题讨论】:

  • 使用说明符%p 打印地址。
  • 搜索并阅读有关在 c 中模拟通过引用传递
  • @JoachimPileborg 谢谢你......但是我已经指定我也在主函数中尝试过......

标签: c pointers casting swap


【解决方案1】:

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

您将局部变量的地址作为指针在 C 中按值传递。如果您想在函数中更改指针并保持此更改在函数外部可见,则必须传递指针的地址。

Here你可以发现你的代码更正了。

你应该在第 33 行添加这个

/* swap values*/
int tmp = *((int*)(*left));
*((int *)(*left)) = *((int *)(*right));
*((int *)(*right)) = tmp;

您是否也希望交换数据。

【讨论】:

  • 主函数中相同的代码产生相同的结果,当然除了地址...
  • @NicholasRoveda 请仔细查看。
  • 好的,抱歉。所以指针的指针交换了,但是a和b的值是一样的……为什么?
  • 不仅是指针的指针,还有指针本身。因为 OP 只想交换指针。这种交换数据也很容易。
  • 好的,完美...最后一点:为什么如果我尝试打印出 *((int *) *((int *)PNT_left)) 程序在打印出时达到 SEGMENTATION FAULT *( (int) left) 有效,因为一开始 *((int *)PNT_left)) = left?
【解决方案2】:

如果你想改变一个指针指向函数内部的位置,你必须将一个指针指针传递给函数。否则,指针会被复制,而您只需在函数内部更改指针。

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

 示例

#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\n",  a_ptr,  b_ptr);
    printf("%i %i\n", *a_ptr, *b_ptr);

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

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

输出:

0x7fff5c663b6c 0x7fff5c663b68
1 2
-- swap --
0x7fff5c663b68 0x7fff5c663b6c
2 1

【讨论】:

  • 好吧,我知道,我不是 C 新手,所以我不明白为什么 main 函数中的相同代码产生相同的结果,它没有交换......事实 *((int *)*((int)PNT_left/right)) 不起作用...
  • @NicholasRoveda:您的代码无法工作,因为您只将 ptr-to-int 传递给函数而不是 ptr-to- ptr-to-int。在swap 内部这行得通,但是这不能 传播到外部swap