2016-06-13 168 views
0

我遇到了問題。我想用一個CopyString()函數將const char* s和char* s複製到緩衝區。它不應該是一個問題,但由於某種原因,我的編譯器不會做我期望它做的事情(我使用PICro的MikroC)。在c中傳遞char *到const char *

void CopyString(char * dest, const char * src, uint8 maxLength){ 
    uint8 i; 
    for(i=0 ; src[i] && (i < maxLength) ; i++){ 
     dest[i] = src[i]; 
    }; 
} 

char test[3]={'2', '0', ' '}; 
CopyString(buf, test, 3);//gives an error (illigal pointer conversion) 
CopyString(buf, (const char *)test, 3); //Doesn't pass the pointer to the array... No idea why not... Do you? 

void CopyString2(char * dest, char * src, uint8 maxLength){ 
    uint8 i; 
    for(i=0 ; src[i] && (i < maxLength) ; i++){ 
     dest[i] = src[i]; 
    }; 
} 
const char test[3]={'2', '0', ' '}; 
CopyString2(buf, "20 ", 3);//All ok 
CopyString2(buf, test, 3); //gives an error (illigal pointer conversion) 

任何人都知道如何做到這一點?目前我在一個C文檔中使用了CopyString2()CopyString(),這個文檔看起來不太好,也不需要。爲什麼會通過char*const char*給出問題? const char*唯一的做法是確保char數組中的數據在函數內不會改變,對吧?

編輯: 在這裏編輯'整個'示例代碼(應該是一個最小,完整和可驗證的例子)。我使用Keil編譯器(我用它來編程ARM單片機的編譯器),它編譯得很好(就像我期望的那樣),但是使用MikroC PIC編譯器(就我所知,這是編譯器的調用方式)。 :

18 384 Illegal pointer conversion main.c (line 18, message no. 384)

23 384 Illegal pointer conversion main.c (line 23, message no. 384)

void CopyString(char * dest, const char * src, unsigned char maxLength){ 
    unsigned char i; 
    for(i=0 ; src[i] && (i < maxLength) ; i++){ 
     dest[i] = src[i]; 
    }; 
} 

void CopyString2(char * dest, char * src, unsigned char maxLength){ 
    unsigned char i; 
    for(i=0 ; src[i] && (i < maxLength) ; i++){ 
     dest[i] = src[i]; 
    }; 
} 

void main(){ 
    char buf[16]={0,}; 
    char test1[3]={'2', '0', ' '}; 
    const char test2[3]={'2', '0', ' '}; 

    CopyString(buf, test1, 3);//gives an error (illigal pointer conversion); 
    CopyString(buf, (const char *)test1, 3); //Doesn't pass the pointer to the array 

    CopyString2(buf, "20 ", 3);//All ok 
    CopyString2(buf, test2, 3); //gives an error (illigal pointer conversion); 
} 
+3

發佈您的*實際代碼*。 – EOF

+0

當發佈關於構建錯誤的問題時,請在問題主體中包含實際錯誤,完整,全部和*未編輯*。還包括編譯器給出的任何可能的信息說明。最好複製粘貼生成日誌。 –

+1

您的示例不是*完整*(請參閱[mcve])。此外,如果您收到編譯錯誤,還會發布*完整*錯誤消息。 – user694733

回答

3

這是一個與如何爲PIC控制器實現const變量有關的問題。在PIC控制器中,RAM和代碼位於不同類型的內存中。 RAM是SD-RAM,代碼是閃存(RAM可通過寄存器和RAM操作訪問,代碼只能自動解碼,或者通過複雜的彙編操作序列讀取)。由於RAM非常小,常量值爲存儲爲代碼存儲器中的返回字面指令(爲了繞過讀取閃存的困難,否則)更大。

所以你不能在兩種類型上都做同樣的操作。這是你需要學習生活的東西。我建議你看看這段代碼的反彙編,看看到底發生了什麼。

+0

edaboard有一個相關的線程http://www.edaboard.com/thread266196.html – Toby

+0

@Toby雖然edaboard線程是關於傳遞一個const char *到一個需要char *的函數。在這種情況下,我可以首先將字符串複製到RAM中,因爲該函數可能需要該字符串不是常量。但我的問題是關於將char *傳遞給接受const char *的函數。我沒有看到爲什麼這樣的函數不接受char *的原因。無論如何,謝謝你的迴應! – Sander

+0

@SurDin我相信它總是發生在單片機的世界裏:常量只存儲在閃存中。如果有編譯器不這樣做,我認爲這是沒有意義的。我也使用Keil(arm)編譯器,它不會將char *的任何問題作爲const char *參數傳遞,儘管它仍然只在flash中存儲const char *。爲什麼PIC會不同?也許是因爲這兩種內存需要不同類型的內存訪問序列。儘管如此,它對我來說並沒有什麼意義。但無論如何;感謝您的回答! – Sander

2

我以前在其他編譯器很久以前看到了這一點 - 注意我以前從未使用過該編譯器。

C的「陣列是一個指針」的概念導致很多與新手的問題。爲了防止這種情況發生,一些編譯器編寫者非常不習慣(這是一個詞!查找它!),並要求您將一個字符的地址傳遞給一個const char *而不僅僅是一個數組。

你可以試試CopyString2(buf, &test[0], 3);

甚至CopyString2(buf, (const char *)&test[0], 3);

+0

您的第一個建議確實導致與之前相同的錯誤。由於某種奇怪的原因,你的第二個建議不會傳遞正確的指針。 – Sander