簡體   English   中英

錯誤:無法將參數'1'的'double *'轉換為'char *'到'void swap(char *,char *,unsigned int)'

[英]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()如果這樣做,可能應該在v1v2指針類型上添加restrict )。 再次,可以將函數static inlinestatic 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變量地址 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:-第二種方式是將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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM