使用 (void **) 做交换功能

问题描述 投票:0回答:3

为什么主函数int i 和j 的值不交换? 在 swap 函数上,我打印 *a 和 *b 地址指向 i 和 j ,可以看到地址发生了变化。 不知道为什么主函数printf i,j的值没有变!

#include <stdio.h>
void swap(void **a, void **b)  
{  
    printf("1swap a address = %d %p\n",*(int*)*a,*a);
    printf("1swap b address = %d %p\n",*(int*)*b,*b);
    void *t;  
    t =*a;  
    *a =*b;  
    *b=t;  
    printf("2swap a address = %d %p\n",*(int*)*a,*a);
    printf("2swap b address = %d %p\n",*(int*)*b,*b);
}  
int main()  
{  
    int i = 3;  
    int j = 5;  
    int *p = &i;  
    int *q = &j;  

    printf(" i address = %p\n",&i);
    printf(" j address = %p\n",&j);

    
    printf("-org i = %d , j = %d\n",i,j);
    swap((void **)&p, (void **)&q);  
    printf("-mod i = %d , j = %d\n",i,j);
    
    printf(" i address = %p\n",&i);
    printf(" j address = %p\n",&j);
    

}  

我预计 I 和 j 的值是互换的

c pointers void
3个回答
1
投票

你的交换函数交换指针

p
q
.

整数交换函数

如果你想交换

i
j
,你不能使用 void(因为编译器不知道要取消引用什么 -
void
没有大小)。另外,不需要指向指针(**)的指针,只需指针就足够了。

void swap(int *a, int *b)
{
    int t;
    t = *a;
    *a = *b;
    *b = t;
}
...
// then use this in main as
swap(&i, &j);
...

您将为要交换的每种类型定义一个新的交换函数。

通用型互换

我不建议这样做。它引入了没有显着收益的漏洞。

如果您坚持

void
(例如,您想将函数用于一般类型),则需要传递另一个参数,即类型的大小(因为编译器不知道您的参数类型)。 不过要小心,这将非常容易出错.

我建议为您需要的每种类型定义新的

swap()
,如前所述。

一般互换定义如下:

void swap(void *a, void *b, size_t size)
{
    // Edit: malloc/free operations aren't as efficient as having the
    //       temporary variable defined on the stack. Keep that in
    //       mind.
    // If you are 106% sure that the size of type you are swapping
    //     won't be bigger than SOME_CONSTANT, you can use:
    //     uint8_t t[SOME_CONSTANT];
    //     instead of malloc/free.
    // Stil I'd prefer defining new swap() for each type you need. 
    void* t = malloc(size);
    memcpy(t, a, size);
    memcpy(a, b, size);
    memcpy(b, t, size);
    free(t);
}
...
// then use this in main as
swap((void*)&i, (void*)&j, sizeof(i));
...

0
投票
  • 这是一个错误和无效的 C:
    (void **)&p
    。您不能将
    int**
    转换为
    void**
    。 C 中唯一具有特殊含义并可以转换为任何其他指针类型的指针是
    void*
    。该特殊规则不适用于
    void**
    “递归”。所以你的函数参数是错误的。
  • 相互交换太多指针没有多大意义。如果这样做,指针
    p
    q
    确实会交换,但不会交换它们指向的内容。你不能改变
    i
    j
    的地址。地址由编译器/链接器分配,而不是由程序员分配。

0
投票

如果要使用双指针:

void swapPointers(void *a, void *b)  
{  
    int *t;  
    int **ai = a;
    int **bi = b;
    t = *ai;  
    *ai = *bi;  
    *bi = t;  
}  

void swapValues(void *av, void *bv, size_t size)  
{  
    int **a = av;
    int **b = bv;
    char array[size];  
    memcpy(array, *a, size);  
    memcpy(*a, *b, size);  
    memcpy(*b, array, size);  
}  

int main()  
{  
    int i = 3;  
    int j = 5;  
    int *p = &i;  
    int *q = &j;  

    printf("Pointers\n");
    printf("-org *p = %d , *q = %d\n",*p,*q);
    swapPointers(&p, &q);  
    printf("-mod *p = %d , *q = %d\n", *p, *q);

    printf("Values\n");
    printf("-org i = %d , j = %d\n",i,j);
    swapValues(&p, &q, sizeof(*p));  
    printf("-mod i = %d , j = %d\n", i, j);
}  
© www.soinside.com 2019 - 2024. All rights reserved.