使用函数参数中的void指针交换两个结构和两个int

时间:2017-02-15 19:54:09

标签: c swap void-pointers

在下面的代码中,我使用单个交换函数来交换两种类型的数据。但是我收到了很多错误。

任何人都可以帮助我,我做错了吗?

#include <stdio.h>
#include <string.h>
#include<stdlib.h>

//我想要交换的结构定义。

struct swapNum
{
    int sal;
    char *c;
};

//我用来交换void函数参数的交换函数。

void swap(void *a,void *b, int size)
{
    if(size == sizeof(*a))
    {
        struct swapNum temp;
        memcpy(temp,a,sizeof(*a));
        memcpy(a,b,sizeof(*b));
        memcpy(b,temp,sizeof(*temp));
    }
    if(size == sizeof(int))
    {
        int *temp;
        *temp = *a;
        *a = *b;
        *b = *a;
    }
}

程序的主要驱动程序部分。

int main(void) {
    char a[10] = "vivek";
    char b[10] = "mishra";
    struct swapNum *A= malloc(sizeof(struct swapNum));
    struct swapNum *B = malloc(sizeof(struc swapNum));
    A->sal = 23;
    A->c = a;

    B->sal = 64;
    B->c = b;

    swap(&A,&B,sizeof(A));

    int x=10,y=20;
    swap(&x,&x,sizeof(b));
    printf("After swapping x : %d y: %d",x,y);

    return 0;
}

我得到的错误。

prog.c: In function 'swap':
prog.c:16:9: error: incompatible type for argument 1 of 'memcpy'
         memcpy(temp,a,sizeof(*a));
         ^
In file included from prog.c:2:0:
/usr/include/string.h:46:14: note: expected 'void * __restrict__' but     argument is of type 'struct swapNum'
 extern void *memcpy (void *__restrict __dest, const void *__restrict __src,
              ^
prog.c:18:30: error: invalid type argument of unary '*' (have 'struct     swapNum')
         memcpy(b,temp,sizeof(*temp));
                              ^
prog.c:18:9: error: incompatible type for argument 2 of 'memcpy'
         memcpy(b,temp,sizeof(*temp));
         ^
In file included from prog.c:2:0:
/usr/include/string.h:46:14: note: expected 'const void * __restrict__' but     argument is of type 'struct swapNum'
 extern void *memcpy (void *__restrict __dest, const void *__restrict __src,
              ^
prog.c:23:9: warning: dereferencing 'void *' pointer
         *temp = *a;
         ^
prog.c:23:17: warning: dereferencing 'void *' pointer
         *temp = *a;
                 ^
prog.c:23:9: error: invalid use of void expression
         *temp = *a;
         ^
prog.c:24:9: warning: dereferencing 'void *' pointer
         *a = *b;
         ^
prog.c:24:14: warning: dereferencing 'void *' pointer
         *a = *b;
              ^
prog.c:2
4:9: error: invalid use of void expression
     *a = *b;
         ^
prog.c:25:9: warning: dereferencing 'void *' pointer
     *b = *a;
     ^
prog.c:25:14: warning: dereferencing 'void *' pointer
         *b = *a;
              ^
prog.c:25:9: error: invalid use of void expression
         *b = *a;
         ^
prog.c: In function 'main':
prog.c:33:36: error: 'struc' undeclared (first use in this function)
  struct swapNum *B = malloc(sizeof(struc swapNum));
                                    ^
prog.c:33:36: note: each undeclared identifier is reported only once for     each function it appears in
prog.c:33:42: error: expected ')' before 'swapNum'
  struct swapNum *B = malloc(sizeof(struc swapNum));
                                          ^

2 个答案:

答案 0 :(得分:0)

有两个问题:

struct swapNum *A= malloc(sizeof(struct swapNum));
struct swapNum *B = malloc(sizeof(struc swapNum));
A->sal = 23;
A->c = a;

B->sal = 64;
B->c = b;

swap(&A,&B,sizeof(A));

sizeof(A)返回指针的大小,您需要sizeof(*A)才能获得正确的对象大小。

而且您不想要&A&B的地址,因为它们已经是指针,更改为

swap(A,B,sizeof(*A));

第二个问题出在swap函数:

void swap(void *a,void *b, int size)
{
    if(size == sizeof(*a))
    { ...

编译警告:

warning: invalid application of ‘sizeof’ to a void type

正如@BLUEPIXY在评论中所建议的那样,使用临时的:

void swap(void *a,void *b, size_t size)
{
    void *temp = malloc(size);

    if (temp) {
        memcpy(temp, a, size);
        memcpy(a, b, size);
        memcpy(b, temp, size);
        free(temp);
    }
}

答案 1 :(得分:0)

这是一种实现通用交换函数的方法,该函数不需要malloc用于临时函数:

void swap_by_bytes (void *a, void *b, size_t sz) {
    char tmp;
    char *ap = a;
    char *bp = b;
    while (sz--) {
        tmp = *ap;
        *ap++ = *bp;
        *bp++ = tmp;
    }
}

虽然逐字节工作正常,但您可以通过逐字复制来改进。

void swap_by_words (void *a, void *b, size_t sz) {
    unsigned tmp;
    char *ap = a;
    char *bp = b;
    while (sz >= sizeof(tmp)) {
        memcpy(&tmp, ap, sizeof(tmp));
        memmove(ap, bp, sizeof(tmp));
        memcpy(bp, &tmp, sizeof(tmp));
        ap += sizeof(tmp);
        bp += sizeof(tmp);
        sz -= sizeof(tmp);
    }
    if (sz > 0) swap_by_bytes(ap, bp, sz);
}

如果大小不是字大小的倍数,则余数将按字节交换。请注意memmove的使用,以防ab重叠。

最后,如果您的平台支持VLA,则可以使用VLA。但是,C.2011使VLA成为可选功能,因此您必须测试其可用性。

void swap (void *a, void *b, size_t sz) {
#ifdef __STDC_NO_VLA__
    swap_by_words(a, b, sz);
#else
    char tmp[sz];
    memcpy(tmp, a, sz);
    memmove(a, b, sz);
    memcpy(b, tmp, sz);
#endif
}