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

#include  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方法时,我在标题中收到错误消息,任何想法为什么? 我看到很多其他post都有解决方案,但没有一个解决了这个问题

编写通用交换函数有很多种方法。 如果它只用于一种类型(因此它不需要是通用的),则不需要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  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; 动态内存分配很昂贵。 我可能会优先使用Implementation 2而不是实现1,因为循环的额外成本很小,使用固定数量的堆栈效果很好。 我没有对这些中的任何一个进行基准测试来validation我的断言。 (如果你正在交换兆字节大小的数据块,你应该再考虑一下 - 使用指针代替。如果你只是交换较小的块,实现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; } 

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

请注意,使用double_swap()generic_swap()意味着代码中不需要强制转换。 最小化演员是A Good Idea™。

另请参见C中的通用数组元素交换 。

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

 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; } 

我在标题中收到错误消息? 因为你传递双变量地址并捕获char*所以编译器说

预期’char *’但参数类型为’double *’。

所以你有两种方法可以将double变量地址 typecastchar*或者使用double*本身捕获。

情况1:

 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; } 

案例2: –第二种方式是类型转换双变量的地址作为char*发送到swap()

 void swap( char *pA, char *pB, unsigned int 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((char*)&a, (char*)&b, sizeof(double)); //typecast &a to (char*)&a printf("linea: %d - despues a(%f) b(%f)\n", __LINE__, a, b); return 0; }