[英]error: cannot convert 'const unsigned char (*)[7]' to 'const unsigned char (*)[]' in initialization
[英]error: cannot convert 'double*' to 'char*' for argument '1' to 'void swap(char*, char*, unsigned int)'
#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方法時,標題中顯示錯誤消息,為什么? 我看到了許多其他的解決方案,但都沒有解決此問題
有許多編寫通用交換函數的方法。 如果僅將其用於一種類型(因此不需要通用),則不需要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()
如果這樣做,可能應該在v1
和v2
指針類型上添加restrict
)。 再次,可以將函數static inline
為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);
}
}
如果內存分配失敗,則不會發生交換。 這很糟糕,因此您可能會退回到“固定大小的緩沖區並分塊交換”,但是無論如何這可能要比這快。
我將優先使用實施2,而不是實施3; 動態內存分配非常昂貴。 我可能會優先於實現1來使用實現2,因為循環的額外成本很小,並且使用固定數量的堆棧效果很好。 我還沒有以任何這些基准作為基准來驗證我的主張。 (如果要交換兆字節大小的數據塊,則可能應該再考慮一遍-使用指針。如果僅交換較小的塊,則實現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()
意味着代碼中不需要強制轉換。 盡量減少演員人數是一個好主意。
另請參見C中的通用數組元素交換 。
好吧,您的函數期望前兩個參數指向一個字符的指針
void swap( char* pA, char* pB, unsigned tam)
但是你傳遞的指針是double
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變量的地址 typecast
為char*
或使用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:-第二種方式是將double變量的地址轉換為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;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.