错误:无法将参数'1'的'double *'转换为'char *'为'void swap(char *,char *,unsigned int)'

时间:2018-04-17 07:14:11

标签: c

#include <stdio.h>

void swap( char* pA,  char* pB, unsigned tam) {
    for( unsigned i = 0; i < tam; i++) {
        char tmp = *pA;
        *pA = *pB;
        *pB = tmp;

        pA = pA + 1;
        pB = pB + 1;
    }
}

int main(int argc, char** argv) {
    double a = 1.0;
    double b = 2.0;

    printf("linea: %d - antes a(%f) b(%f)\n", __LINE__, a, b);

    swap(&a, &b, sizeof(double)); //This line gives the error

    printf("linea: %d - despues a(%f) b(%f)\n", __LINE__, a, b);
}

当我调用swap方法时,我在标题中收到错误消息,任何想法为什么?我看到很多其他帖子都有解决方案,但没有一个解决了这个问题

3 个答案:

答案 0 :(得分:2)

编写通用交换功能有很多种方法。如果它只用于一种类型(因此它不需要是通用的),则不需要size参数,你可以传递相关类型的指针(问题中为double *)并交换使用间接。

extern void double_swap(double *d1, double *d2);

void double_swap(double *d1, double *d2)
{
    double d = *d1;
    *d1 = *d2;
    *d2 = d;
}

将其变为:

可能会有好处
static inline void double_swap(double *d1, double *d2)
{
    double d = *d1;
    *d1 = *d2;
    *d2 = d;
}

这可以放在标题中并安全使用。

如果它将用于多种类型,则应在函数参数中使用void *(对于类型的大小,应使用size_t。)

/*
** This declaration belongs in a header if there is more than one
** source file that uses it.  If there is only one file, then it
** should be declared and defined as a static function.  If the
** header doesn't include any other headers that define size_t,
** it should #include <stddef.h> as that's the smallest header
** that does define size_t.  You could make the function static
** inline instead of extern, even if it is in a header.
*/
extern void generic_swap(void *v1, void *v2, size_t size);

/* Implementation 1: Using VLA */
void generic_swap(void *v1, void *v2, size_t size)
{
    char sp[size];
    memmove(sp, v1, size);
    memmove(v1, v2, size);
    memmove(v2, sp, size);
}

如果您不介意生活危险,可以使用memcpy()(如果您这样做,可以将restrict添加到v1v2指针类型)。同样,函数可能会static inline达到良好效果 - 这也适用于下面的其他实现。

如果您不喜欢在堆栈上分配大对象的想法,您可以以块的形式复制数据,但是您必须更加努力地工作。

enum { CHUNK_SIZE = 64 };

static inline size_t min_size(size_t x, size_t y) { return (x < y) ? x : y; }

/* Implementation 2: Using a fixed size buffer */
void generic_swap(void *v1, void *v2, size_t size)
{
    unsigned char sp[CHUNK_SIZE];
    unsigned char *p1 = v1;
    unsigned char *p2 = v2;
    size_t chunk;
    while ((chunk = min_size(size, CHUNK_SIZE)) != 0)
    {
        memmove(sp, p1, chunk);
        memmove(p1, p2, chunk);
        memmove(p2, sp, chunk);
        p1 += chunk;
        p2 += chunk;
        size -= chunk;
    }
}

尽管GCC允许,C标准表示你不能增加void *,因为没有已知大小可以增加它。这就是指针转换为unsigned char *的原因。显然,您可以调整块大小以适合您的系统。 16..1024范围内的任何2的幂都可以使用,如果您愿意,可以使用除2的幂之外的其他值。

如果您不介意开销,可以动态分配缓冲区:

/* Implentation 3: Using dynamic memory allocation */
void generic_swap(void *v1, void *v2, size_t size)
{
    char *sp = malloc(size);
    if (sp != 0)
    {
        memmove(sp, v1, size);
        memmove(v1, v2, size);
        memmove(v2, sp, size);
        free(sp);
    }
}

如果内存分配失败,则交换不会发生。这很糟糕,所以你可能会回到固定大小的缓冲区并交换块,但这可能比这更快。

我会使用Implementation 2而不是Implementation 3;动态内存分配很昂贵。我可能会使用实现2而不是实现1,因为循环的额外成本很小,并且使用固定数量的堆栈效果很好。我没有基准测试任何 这些来验证我的断言。 (如果您正在交换兆字节大小的数据块,您应该再考虑一下 - 使用指针代替。如果您只是交换较小的块,则实现1非常简单且安全。)

使用任何通用交换实现,您的主程序将变为:

int main(void)
{
    double a = 1.0;
    double b = 2.0;

    printf("linea: %d - antes   a(%f) b(%f)\n", __LINE__, a, b);
    generic_swap(&a, &b, sizeof(double));
    printf("linea: %d - despues a(%f) b(%f)\n", __LINE__, a, b);
    return 0;
}

我假设至少generic_swap()的声明在main()开始之前可用。

请注意,使用double_swap()generic_swap()表示代码中不需要强制转换。最小化演员阵容是一个好主意。

另见Universal array element swap in C

答案 1 :(得分:1)

好吧,你的函数期望指向前两个参数的字符

void swap( char* pA,  char* pB, unsigned tam) 

但你传递的指针是双重

double a = 1.0;
double b = 2.0;
swap(&a, &b, sizeof(double)); //This line gives the error

以下内容允许您交换两个双打,除非您有特定原因要一次交换一个字节:

void swap(double *pA, double *pB, unsigned int tam) {
    double tmp = *pA;
    *pA = *pB;
    *pB = tmp;
}

答案 2 :(得分:0)

我在标题中收到错误消息?因为您传递的是双变量地址并且正在使用ftp_append( resource $ftp, string $remote_file, string $local_file [, int $mode = FTP_IMAGE ] ) ,所以编译器会说

  

期望'char *'但参数的类型为'double *'。

因此,您有两种方式char*双变量地址<{1}}或typecast本身。

案例1:

char*

案例2: -  第二种方法是将double*的双变量地址强制转换为void swap( double* pA, double* pB, unsigned int tam) { double tmp = *pA; *pA = *pB; *pB = tmp; } int main(int argc, char** argv) { double a = 1.0; double b = 2.0; printf("linea: %d - antes a(%f) b(%f)\n", __LINE__, a, b); swap(&a, &b, sizeof(double)); //This line gives the error printf("linea: %d - despues a(%f) b(%f)\n", __LINE__, a, b); return 0; }

char*